diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..59d9a3a3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..ab21f32d --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [Ks89] diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..a0f86b03 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,69 @@ + + + + +## I'm submitting a... + +

+[ ] Regression (a behavior that used to work and stopped working in a new release)
+[ ] Bug report  
+[ ] Feature request
+[ ] Documentation issue or request
+[ ] Support request
+
+ +## Current behavior + + + +## Expected behavior + + + +## Minimal reproduction of the problem with instructions + + + +## What is the motivation / use case for changing the behavior? + + + +## Environment (the most important section to fill very carefully) + +

+- @ks89/angular-modal-gallery version: X.X.X
+- Node version: X.X.X  
+- npm version: X.X.X  
+- Operating System and version:  
+- Angular version: X.Y.Z 
+- angular-cli version (or SystemJS/Webpack): X.Y.Z 
+- I'm using Server Side Rendering with angular-universal: YES/NO
+- I'm compiling with mode: DEBUG / PROD / PROD with AOT
+
+
+
+Browser:
+- [ ] Chrome (desktop) version XX
+- [ ] Chrome (Android) version XX
+- [ ] Chrome (iOS) version XX
+- [ ] Firefox version XX
+- [ ] Safari (desktop) version XX
+- [ ] Safari (iOS) version XX
+- [ ] IE version XX
+- [ ] Edge version XX
+
+Others:
+
+
+ + + diff --git a/.github/codeql-config.yml b/.github/codeql-config.yml new file mode 100644 index 00000000..d4602521 --- /dev/null +++ b/.github/codeql-config.yml @@ -0,0 +1,5 @@ +paths: + - projects +paths-ignore: + - examples + - src diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000..ad8da1d2 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,72 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ develop ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ develop ] + schedule: + - cron: '38 16 * * 3' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'javascript' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + config-file: ./.github/codeql-config.yml + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..da086c4d --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,88 @@ +name: angular-modal-gallery + +on: + push: + paths-ignore: + - 'node_modules' + - '../../examples/angular-cli-19/node_modules' + - 'examples/angular-cli-material/node_modules' + - 'examples/universal/node_modules' + +jobs: + + angular-modal-gallery: + name: "angular-modal-gallery" + timeout-minutes: 20 + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [ 20.x ] + + steps: + - uses: actions/checkout@v4 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + + - name: Switch to a specific npm version + run: | + npm install -g npm@10 + npm cache verify + + - name: Installing all deps + run: | + npm ci + cd examples/angular-cli-19 + npm ci + cd ../.. + cd examples/angular-cli-material + npm ci + cd ../.. + cd examples/universal + npm ci + cd ../.. + + - name: Building main web app + run: | + npm run build:all + npm run build:main:dev + npm run build:main:prod + + - name: Building angular-cli example + run: | + cd examples/angular-cli-19 + npm run build:dev + npm run build:prod + cd ../.. + + - name: Building angular-cli-material example + run: | + cd examples/angular-cli-material + npm run build:dev + npm run build:prod + cd ../.. + + - name: Building universal example + run: | + cd examples/universal + npm run build:dev + npm run build:prod + cd ../.. + + - name: Running tests (with retry on failure) + uses: nick-fields/retry@v2 + with: + max_attempts: 3 + timeout_minutes: 10 + command: | + npm test + + - name: Coveralls + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + path-to-lcov: './coverage/ks89/angular-modal-gallery/lcov.info' diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..a9e4b9d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,58 @@ +# Created by .ignore support plugin (hsz.mobi) +### Node template +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Dependency directories +node_modules + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Yarn Integrity file +.yarn-integrity + +# IntelliJ +.idea + +# dotenv environment variables file +.env + +# System files +.DS_Store +Thumbs.db + +# Compiled files +*.metadata.json +*.ngfactory.ts +*.ngsummary.json +**/dist +**/aot +**/.awcache +**/dll +**/@ks89/ +.angular/ + +# Docs +docs/ + +# Tests +**/coverage/ + +# Examples +examples/angular-cli-19/dist/ +examples/angular-cli-material/dist/ +examples/universal/dist/ +examples/universal/out-tsc/ + diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..e69de29b diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..4c0457a0 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,54 @@ +/.git/ +/.idea/ + +/.github/ +/@ks89/ +/coverage/ +/docs/ +**/dist/ +**/node_modules/ +reports/ + +examples/angular-cli-19/dist/ +examples/angular-cli-material/dist/ +examples/universal/dist/ +examples/universal/server.ts +examples/universal/out-tsc/ + +**/*.spec.ts +**/e2e/ + +**/tslint.json + +**/webpack.*.js + +**/package.json +**/package-lock.json +**/yarn.lock + +**/.angular-cli.json +**/.editorconfig +**/.bootstraprc +**/*.properties +**/*.map +**/*.ejs +**/*.html +**/*.md +**/*.yml +**/*.scss +**/*.css +**/*.jpg +**/*.jpeg +**/*.png +**/*.ico +**/*.svg +**/*.tgz + +**/.gitignore +/**/.gitkeep +**/.prettierignore +**/.snyk +**/.npmignore + +**/.DS_Store +**/Thumbs.db diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 00000000..5fa98f4c --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,10 @@ +{ + "bracketSpacing": true, + "printWidth": 155, + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "none", + "useTabs": false, + "arrowParens": "avoid" +} diff --git a/.sass-lint.yml b/.sass-lint.yml new file mode 100644 index 00000000..ca44ac0e --- /dev/null +++ b/.sass-lint.yml @@ -0,0 +1,103 @@ +# inspired by https://gist.github.com/amwelles/293e880843eb800a9942 + +files: + include: 'sass/**/*.s+(a|c)ss' + ignore: + - '@ks89/**/*.*' + - 'coverage/**/*.*' + - 'dist/**/*.*' + +rules: + # Extends + extends-before-mixins: 1 + extends-before-declarations: 1 + placeholder-in-extend: 0 + + # Mixins + mixins-before-declarations: + - 1 + - + exclude: + - breakpoint + + # Line Spacing + one-declaration-per-line: 1 + empty-line-between-blocks: 0 + single-line-per-selector: 1 + + # Disallows + no-color-keywords: 0 + no-color-literals: 0 + no-css-comments: 1 + no-debug: 1 + no-duplicate-properties: 1 + no-empty-rulesets: 1 + no-extends: 0 + no-ids: 0 + no-important: 1 + no-invalid-hex: 1 + no-mergeable-selectors: 1 + no-misspelled-properties: 1 + no-qualifying-elements: + - 1 + - + allow-element-with-attribute: true + allow-element-with-class: true + no-trailing-zero: 1 + no-transition-all: 1 + no-url-protocols: 1 + no-vendor-prefixes: 1 + no-warn: 1 + + # Nesting + force-attribute-nesting: 0 + force-element-nesting: 1 + force-pseudo-nesting: 1 + + # Name Formats + function-name-format: 1 + mixin-name-format: 1 + placeholder-name-format: 1 + variable-name-format: 1 + + # Style Guide + border-zero: 1 + brace-style: + - 1 + - + allow-single-line: false + clean-import-paths: 1 + empty-args: 1 + hex-length: 1 + hex-notation: 1 + indentation: 1 + leading-zero: 1 + nesting-depth: + - 1 + - + max-depth: 3 + property-sort-order: + - 0 + - + order: concentric + quotes: + - 1 + - + style: double + shorthand-values: 1 + url-quotes: 1 + variable-for-property: 1 + zero-unit: 1 + + # Inner Spacing + space-after-comma: 1 + space-before-colon: 1 + space-after-colon: 1 + space-before-brace: 1 + space-before-bang: 1 + space-after-bang: 1 + space-between-parens: 1 + + # Final Items + trailing-semicolon: 1 + final-newline: 1 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..5c603d2f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,1596 @@ +# 12.0.0 + +### Features + +- Angular 18 is required **(BREAKING CHANGE)** + + +# 11.1.2 + +### Bugfixes + +- fix ngOnChanges method to access changes.config and not changes.plainGalleryConfig (always undefined) #268 (reported by @Dea1100) + + +# 11.1.1 + +### Refactor + +- remove circular dependency between ModalGalleryService and ModalGalleryComponent #262 (implemented by @StenCalDabran) + + +# 11.1.0 + +### Features + +- add sources to improve LCP, loading and fetchpriority attributes #260 (implemented by @luca-peruzzo) + +### Tests + +- add missing `keyboard-navigation.directive` test file + +### Examples + +- fix bad 'add image' button CSS in all examples + +### Docs + +- fix bad docs in `swipe.directive` + + +# 11.1.0-rc.1 + +### Features + +- add sources to improve LCP, loading and fetchpriority attributes #260 (implemented by @luca-peruzzo) + + +# 11.0.0 + +**Migrate from 10.0.0 to 11.0.0 - Check the official guide [HERE](https://ks89.github.io/angular-modal-gallery-2023-v11.github.io/)** + +### Features + +- remove `hammerjs` dependency (because deprecated) to mange swipe events preferring a custom directive #218 **(BREAKING CHANGE)** +- remove `mousetrap` dependency to manage ctrl+s/meta+s event to save the current image in modal-gallery component. + This in a very important change, because from now you won't be able to customize ctrl+s/meta+s shortcuts #237 **(BREAKING CHANGE)** + + +# 11.0.0-rc.1 + +**Migrate from 10.0.0 to 11.0.0 - Check the official guide [HERE](https://ks89.github.io/angular-modal-gallery-2023-v11.github.io/)** + +### Features + +- remove `hammerjs` dependency (because deprecated) to mange swipe events preferring a custom directive #218 **(BREAKING CHANGE)** +- remove `mousetrap` dependency to manage ctrl+s/meta+s event to save the current image in modal-gallery component. + This in a very important change, because from now you won't be able to customize ctrl+s/meta+s shortcuts #237 **(BREAKING CHANGE)** + + +# 10.0.1 + +### Bugfixes + +- fix examples, readme file and Github Action workflow + + +# 10.0.0 + +### Features + +- Angular 15 is required **(BREAKING CHANGE)** + + +# 10.0.0-rc.1 + +### Features + +- Angular 14 is required **(BREAKING CHANGE)** + + +# 9.1.0 + +A special thanks to @locinus for PRs #254 and #257 + +### Features + +- modal gallery previews can be customized using a template #254 (see example F3 - (id=902) in this repository), implemented by @locinus + + +### Bugfixes + +- clicking the right image arrow always shifts the displayed previews, even in cases where it shouldn't, for instance for n>=3 and current=0 (root cause of 'clipping' effects when navigating away from first/last preview) #257, implemented + by @locinus +- the number of displayed previews sometimes oscillate between n (number of requested previews in config) and n-1/n+1 while navigating (for example for n=4 or n=5) #257, implemented by @locinus +- when opening the modal and navigating to the last preview by clicking on the right preview arrow, it's impossible to then click on the left preview arrow (same from last to first and clicking on the right preview arrow) #257, implemented + by @locinus +- In infinite sliding, the left and right preview arrows should be always visible (except if nbPreviews < nbImages) #257, implemented by @locinus + + +# 9.1.0-beta.2 + +Pull request #257 by @locinus +Simplifies and uniformizes the calculation of previews indexes, in the different navigation cases (changes of current images, uses of previews arrows). + +### Bugfixes + +- clicking the right image arrow always shifts the displayed previews, even in cases where it shouldn't, for instance for n>=3 and current=0 (root cause of 'clipping' effects when navigating away from first/last preview) +- the number of displayed previews sometimes oscillate between n (number of requested previews in config) and n-1/n+1 while navigating (for example for n=4 or n=5) +- when opening the modal and navigating to the last preview by clicking on the right preview arrow, it's impossible to then click on the left preview arrow (same from last to first and clicking on the right preview arrow) +- In infinite sliding, the left and right preview arrows should be always visible (except if nbPreviews < nbImages) + + +# 9.1.0-beta.1 + +### Features + +- modal gallery previews can be customized using a template #254 (see example F3 - (id=902) in this repository), implemented by @locinus + + +# 9.0.1 + +### Bugfixes + +- update some old links to doc website + + +# 9.0.0 + +**Migrate from 8.0.0 to 9.0.0 - Check the official guide [HERE](https://ks89.github.io/angular-modal-gallery-2021-v9.github.io/)** + +### Features + +- remove legacy mode in carousels (drop IE11) #235 **(BREAKING CHANGE)** +- remove keyCode in keyboard-navigation-directive, because deprecated #200 **(BREAKING CHANGE)** +- cleanup download image code in modal-gallery.component (drop IE11 and Edge legacy) #228 **(BREAKING CHANGE)** +- requestFullscreen and exitFullscreen return promises. **(BREAKING CHANGE)** + It's not easy to manage all cases in the right way, so at the moment I added only an error in case of catch clause #233 **(BREAKING CHANGE)** +- Remove AdvancedLayout from PlainGallery, because already unused in v8.x.x #238 **(BREAKING CHANGE)** +- make LibConfig interface private, to expose ModalLibConfig, PlainLibConfig and CarouselLibConfig #232 **(BREAKING CHANGE)** +- carousel component accepts CarouselLibConfig as input instead of all parameters to be consistent with changes made in v8.0.0 #229 **(BREAKING CHANGE)** +- remove `[showGallery]` input from plain-gallery component, because it's unused #239 **(BREAKING CHANGE)** +- rename `(showImage)` output into `(clickImage)` for plain-gallery #240 **(BREAKING CHANGE)** +- rename `(showImage)` output into `(changeImage)` for carousel #240 **(BREAKING CHANGE)** +- when modal-gallery opens with image index 0 or length - 1, it emits first/last Image events #241 **(BREAKING CHANGE)** +- remove emitButtonAfterHook in closeGallery methods **(BREAKING CHANGE)** + +### Bugfixes + +- improve error message if you pass an empty array of images to the carousel #209 + +### Examples + +- add examples with 0 images to modal-gallery, carousel and plain-gallery #242 +- remove stackblitz demo because not working properly like with version 8.0.0 + +### Tests + +- improve modal-gallery.component tests to validate also html elements #231 + +### Docs + +- migration guide from 8.0.0 to 9.0.0 +- upgrade doc website to bootstrap 5.x.x #236 +- many fixes to the API and examples input tables (errors made with 8.0.0) +- general improvement to the doc to show default values in a cleaner way +- remove LibConfig interface and use the newer interfaces + +**Migrate from 8.0.0 to 9.0.0 - Check the official guide [HERE](https://ks89.github.io/angular-modal-gallery-2021-v9.github.io/)** + + +# 8.0.1 + +### Bugfixes + +- fix `config.service.ts` adding `providedIn: 'root'` to the service (fixes #244) reported by @dreiquevada + + +# 8.0.0 + +### Features + +- Migrate to angular/cdk to fix all issues with angular/material **(Breaking Change)** (fixes #137, #111, #95) +- Split plain-gallery and modal-gallery decoupling those components. Instead, define new APIs to open modal-gallery as a service **(Breaking Change)** +- upgrade to Angular 12 and angular-cli 12 +- Force Angular >= 12 as minimum supported version. **(Breaking Change)**. +- remove support to both Angular 6, 7, 8, 9, 10 and 11 **(Breaking Change)** +- remove Module.forRoot() **(Breaking Change)** +- move keyboard configuration into libconfig (permits different configuration for every instance of the library). **(Breaking Change)** +- use IVY as recommended by Angular team ('partial' in tsconfig) +- Add ability to set fallback image #194 **(Breaking Change)** +- Add a way to disable titles if requested by the user #179 **(Breaking Change)** +- remove size from plainGallery Image interface #206 **(Breaking Change)** - reported by @studiocuboweb +- add new param to previewConfig to display previews on small screens #213 (pull request #214 by vlafranca) +- Change the background color of modal gallery #225 (requested by @danurasenan here) +- Carousel has a new input "[disableSsrWorkaround]="true"" to use modals in carousels with SystemJS **(Breaking Change)**. + Also, every time you need to open modal gallery, you must pass to LibConfig this code: + ``` + keyboardServiceConfig: { + shortcuts: ['ctrl+s', 'meta+s'], + disableSsrWorkaround: true + } + ``` +- new modal-gallery CSS classes used to set the backdrop **(BREAKING CHANGES)** + + ``` + .ks-modal-gallery-backdrop { + background: #000 !important;; + opacity: 0.85 !important;; + } + + .ks-modal-gallery-panel { + z-index: 90000 !important; + } + ``` + +### CI +- remove AppVeyor +- remove CircleCi +- remove Travis Ci +- add Github Actions Ci +- add Github CodeQL +- remove npm's codeclimate coverage reporter to use the new version +- add Security Policy in SECURITY.MD + +### Tests +- update tests to the new APIs and components + +### Examples +- upgrade all examples with Angular 12 +- remove SystemJS example +- create new stackblitz example with Angular 12 and Ivy enabled + +### Docs +- new doc website [HERE](https://ks89.github.io/angular-modal-gallery-2020-v8.github.io/) + +## DEPRECATION WARNINGS + +**Attention! Angular support for Microsoft's Internet Explorer 11 (IE11) is deprecated and will be removed in Angular v13.** +**For the same reason, from angular-modal-gallery 8.0.0, IE11 has been deprecated.** +**At the moment it's still working, but it will be removed in angular-modal-gallery 9.0.0.** + + +# 8.0.0-rc.1 +### Features +- upgrade project to Angular 12. This is the minimum required version from now. **BREAKING CHANGE** + +### Bugfixes +- remove `document.body.style.overflow = ...` to prevent weird behaviour. @angular/cdk is enough to block window scrolling. + +### CI +- remove all CIs to use only Github Actions + +### Tests +- upgrade unit testing + +### Examples +- remove SystemJS example +- upgrade all angular-cli examples to Angular 12, because it's the minimum required version from now + +### Docs +- first public live version of [documentation website](https://ks89.github.io/angular-modal-gallery-2020-v8.github.io/) +- improved doc website adding a more step-by-step introduction to the key concepts of the library + +## DEPRECATION WARNINGS + +**Attention! Angular support for Microsoft's Internet Explorer 11 (IE11) is deprecated and will be removed in Angular v13.** +**For the same reason, from angular-modal-gallery 8.0.0, IE11 has been deprecated.** +**At the moment it's still working, but it will be removed in angular-modal-gallery 9.0.0.** + +
+ +**This is a beta version without a documentation** + + +# 8.0.0-beta.5 +### Features +- add new param to previewConfig to display previews on small screens #213 (pull request #214 by vlafranca) +- remove the useless nested 'config' object in ModalGalleryConfig interface. + + To upgrade from all previous 8.0.0 beta releases, change all .open(...) methods passing an object without the nested 'config' object + +
+ +**This is a beta version without a documentation** +**If you want to try it, check examples/angular-cli-10 to get tons of working examples** + + +# 8.0.0-beta.4 +### Features +- new modal-gallery CSS classes used to set the backdrop **(BREAKING CHANGES)** + + To upgrade from all previous 8.0.0 beta releases, change your global styles.scss from: + + ``` + .cdk-overlay-backdrop.cdk-overlay-backdrop-showing.dark-backdrop { + background: #000; + opacity: 0.85 !important; + } + + .cdk-overlay-container { + z-index: 90000 !important; + } + ``` + + to : + + ``` + .ks-modal-gallery-backdrop { + background: #000 !important;; + opacity: 0.85 !important;; + } + + .ks-modal-gallery-panel { + z-index: 90000 !important; + } + ``` + +
+ +**This is a beta version without documentation** +**If you want to try it, check examples/angular-cli-10 to get tons of working examples** + + +# 8.0.0-beta.3 +### Features +- upgrade to Angular 10. **(Breaking Change)**. +- remove Angular 8 support. **(Breaking Change)**. + +### Demos +- update all examples with Angular 10, except for angular-cli-9 + +
+**This is a beta version without documentation** +**If you want to try it, check examples/angular-cli-10 to get tons of working examples** + + +# 8.0.0-beta.2 +### Features +- restore Server Side Rendering support with Universal #183. **(Breaking Change)**. +- Carousel has a new input "[disableSsrWorkaround]="true"" to use modals in carousels with SystemJS **(Breaking Change)**. + Also, every time you need to open modal gallery, you must pass to LibConfig this code: + ``` + keyboardServiceConfig: { + shortcuts: ['ctrl+s', 'meta+s'], + disableSsrWorkaround: true + } + ``` + +### Demos +- update all LibConfigs in SystemJS demo to prevent crashes. Because, now disableSsrWorkaround must be passed manually in every LibConfig. This is a + breaking change (see above). + + +# 8.0.0-beta.1 +### Features +- Migrate to angular/cdk to fix all issues with angular/material **(Breaking Change)** (fixes #137, #111, #95) +- Split plain-gallery and modal-gallery decoupling those components. Instead, define new APIs to open modal-gallery as a service **(Breaking Change)** +- upgrade to Angular 9 and angular-cli 9, removing support for both Angular 6 and 7 **(Breaking Change)** +- remove Module.forRoot() **(Breaking Change)** +- move keyboard configuration into libconfig (permits different configuration for every instance of the library). **(Breaking Change)** +- Add ability to set fallback image #194 **(Breaking Change)** +- Add a way to disable titles if requested by the user #179 **(Breaking Change)** + +### Demos +- upgrade all examples (except for universal, at the moment) +- remove angular-cli-6 example and add angular-cli-9 +- upgrade systemjs example + +### Internal library changes +- remove npm's codeclimate coverage reporter to use the new version +- experiment with Angular IVY + +### Known issues +Still not working with universal (SSR), please be patient! + +
+**This is a beta version, with SSR support missing and no documentation at all** +**If you want to try it, check examples/angular-cli-9 to get tons of working examples** + + +# 7.2.7 +### Bugfixes +- support Angular 11 preventing a build issue. Fixed by @cihancelen with pull request #216. + + +# 7.2.6 +### Bugfixes +- carousel in IE11 legacy mode shows wrong title on previous arrow (it's the same of next arrow, instead of previous). Fixed by @aslubsky with pull request #199. + + +# 7.2.5 +### Bugfixes +- carousel autoPlay ignores configPlay.autoPlay = false. Reported and fixed by @aslubsky (issue #191 and pull request #192) + + +# 7.2.4 +### Bugfixes +- fix again issue #188 reported by @jagoda-b: if first/last image, next/prev arrows show hand cursor. + + +# 7.2.3 +### Bugfixes +- fix another issue about side previews, because they where invisible **(IMPORTANT BUG FIX)** +- fix issue #188 reported by @jagoda-b: if first/last image, next/prev arrows are invisible but clickable. Also "title" is still visible. + + +# 7.2.2 +### Bugfixes +- fix issue #186 about vertical scrolling with carousel, caused by HammerJs (solution received by @mohaxspb as a pull request https://github.com/Ks89/angular-modal-gallery/pull/187) + + +# 7.3.0-rc.1 +### Features +- **support image download also as base64** +- **add config.service to store and share library configuration** (this is used only inside the library and it's a core feature for future releases like 8.0.0) #180 + +### Bugfixes +- **if slideConfig is undefined, side previews should be visible, because they are enabled by default.** Fixed thanks to the new configService and unit testing. + +### Demos +- fix some issues and update all examples +- fix example B23 to enable delete button + +### Testing +- update tests + + +# 7.2.1 +### Bugfixes +- fix issue cannot read property 'pauseOnHover' of undefined (requested by @alvinmactal #177) + + +# 7.2.0 +### Features +- add autoPlay to modal-gallery (requested by @hn6pot #152) + +### Demos +- add a new demo to explain how to handle an image array with the same image path multiple times without caching issues (requested by @shakerica #171) +- add demos with autoplay feature in modal-gallery (to explain the feature requested by @hn6pot #152) + +### Documentation +- update doc website with the new feature and examples (requested by @shakerica #171) +- add warning about same image multiple times in images array (requested by @shakerica #171) + +### Testing +- update tests + + +# 7.1.0 +### Features +- emit events also when you click on a preview (requested by @srtab #165) + +### Testing +- update tests + +### Internal library changes +- clickPreview's Output emits ImageModalEvent instead of Image + + +# 7.0.1 +### Bugfixes +- show carousel's dots also when legacyIe11Mode is enabled + + +# 7.0.0 +### Features +- **new carousel component with previews (also with legacyIE11Mode to support IE11 :))** **HUGE FEATURE!!!!** +- **add @angular/cdk as required dependency** **(BREAKING CHANGE)** +- gallery ids must be unique across the whole application **(BREAKING CHANGE)** +- requires rxjs >= 6 **(BREAKING CHANGE)** +- requires angular >= 6 **(BREAKING CHANGE)** +- add top and bottom margins to thumbs in plain gallery #169 (requested by @MiaAlSaif) **BREAKING CHANGE** +- new method in GalleryService called 'navigateGallery' + +### Vulnerabilities +- fix a security issue in modal-gallery when you are using the navigate button to an external url with target _blank. + In this way I prevent "Reverse Tabnabbing"'s attacks. To fix this issue I used this standard technique: https://developer.mozilla.org/en-US/docs/Web/API/Window/open + +### Chores +- update readme with a better layout (table of contents, images and so on) + +### Demos +- add new carousel examples to all demos +- add new carousel ie11 examples to all demos +- create a new GUI for all examples based on the official documentation website v7 +- add new demo angular-cli-6 to test this library also on angular 6 +- upgrade both angular-cli, universal and angular-cli-material to angular 7, angular-cli 7 and angular-material 7 +- update all examples, adding @angular/cdk + +### Documentations +- add all features and examples of Carousel +- improve documentation website with a new Font +- improve performance with service workers, external fonts and optimized images and SVGs +- fix SEO issues about H1-H6 +- fix SEO issues about page titles and best practices about icons, themes, manifest.json and so on +- add Google Analytics +- update to Angular 7 and angular-cli 7 +- improve SSR and prerender (still not possible on Github so I'll release it on a real server) +- remove unused libs like ng-bootstrap, jquery, popper and others +- first implementation of app-shell (still no working because of some incompatibilities with third party libs) +- remove sidebar for all pages except for demo and features +- add accordion to demo sidebar, also saved in local storage +- new documentation website https://github.com/Ks89/angular-modal-gallery-2018-v7.github.io +- rewrite navbar without bootstrap +- improve sidebar for both features and demo +- upgrade to the latest alpha version of angular-modal-gallery +- improve colors and accessibility +- fix compatibility table in homepage +- update default values page +- add new logo +- replace navbar brand text with the new logo +- replace github iframes with badges +- add migration guide +- update doc with new responsive breakpoints for carousel's previews +- swipe sidebar and content in features and examples to improve readability on smartphones + +### Internal library changes +- migrate to the official ng lib features in angular-cli >= 6.2 +- upgrade to angular-cli 7 final and Angular 7 final +- use `@Injectable(provideIn: 'root')` in galleryService and idValidatorService +- upgrade to angular-cli 7 and Angular 7 +- upgrade to Typescript 3.1.x +- add new MaxDirective to change max-height and max-width fully tested +- fix build internal docs with typedoc, using the latest @next release to support typescript 3.1.x +- replace KeyboardEvent keyCode with code, because deprecated +- update internal documentation (npm run docs) + +### Testing +- fix code coverage for library's unit testing +- add unit testing for id-validator service and improve it forcing **integer** id values **> 0** **(BREAKING CHANGE)** +- add missing unit test for accessible.component +- add tests for carousel and carousel-previews components + +### CI +- upgrade CI config files to Node 10 + +Differences from rc.2: +- doc website with a warning to use playconfig.interval >= 0 +- some bug fixes to doc website +- improve unit testing +- fix other issues to support IE11 +- temporary remove deprecation warning of `forRoot()`, because I didn't implement an alternative yes +- fix github badges + + +# 7.0.0-rc.2 +### Vulnerabilities +- fix a security issue in modal-gallery when you are using the navigate button to an external url with target _blank. + In this way I prevent "Reverse Tabnabbing"'s attacks. To fix this issue I used this standard technique: https://developer.mozilla.org/en-US/docs/Web/API/Window/open + +### Bugfixes +- fix accessibility (aria-label and title) of image arrows in carousel component + +### Refactoring +- remove carousel's dots properties from AccessibilityConfig, because unused. Instead, carousel uses the same of modal-gallery + +### Documentations +- small fixes to documentation website + +### Testing +- add missing unit test for accessible.component +- add initial unit test impl for carousel.component + +### Demos +- update all carousel's examples adding all mandatory parameters to all inputs in html without violating interfaces + +### Internal library changes +- replace KeyboardEvent keyCode with code, because deprecated + + +# 7.0.0-rc.1 +### Bugfixes +- fix bug when carousel's previews are small and legacy mode for IE11 is enabled #144 + +### Documentations +- add new example to doc website with custom breakpoints example + + +# 7.0.0-beta.4 +### Features +- **add @angular/cdk as required dependency** (mandatory also in beta-3, but I forgot to add it :)) **BREAKING CHANGE** +- remove left and right margin of carousel's previews (probably I'll add they again in next releases with a dedicated interface to configure they) +- updated icon + +### Refactoring +- cleanup source removing older experiments + +### Internal library changes +- write full internal documentation (npm run docs) + +### Demos +- create a new GUI for all examples based on the official documentation website v7 +- update all examples, adding @angular/cdk (also to SystemJS example), because it was missing + +### Documentations +- swipe sidebar and content in features and examples to improve readability on smartphones +- update icons + + +# 7.0.0-beta.3 +### Features +- add top and bottom margins to thumbs in plain gallery #169 (requested by @MiaAlSaif) **BREAKING CHANGE** +- add new api to configure the height of carousel's previews based on breakpoints #144 + +### Bugfixes +- fix content projection bug (it was working only with legacy mode enabled) + +### Demos +- add new carousel examples to all demos + +### Documentations +- update doc with new responsive breakpoints for carousel's previews + + +# 7.0.0-beta.2 +### Features +- add new input param to enable legacyIE11Mode. This is required only to support IE11. If you don't need this stupid obsolete browser, you shouldn't use it. +- add deprecation to `forRoot()` method. Probably I'll remove it in version 8.x.x +- new library logo + +### Bugfixes +- fix wrong carousel's width on both Firefox, IE11 and Edge (IE11 still stretches carousel images) +- fix many issues on IE11 + +### Internal library changes +- upgrade to angular-cli 7 final and Angular 7 final +- use `@Injectable(provideIn: 'root')` in galleryService and idValidatorService + +### Refactor +- use internal ksSize and ksMaxSize directives when possible in carousel.html + +### Demos +- upgrade all examples to Angular 7 and cli 7 if necessary +- add new carousel ie11 page to all examples + +### Documentations +- add new logo +- replace navbar brand text with the new logo +- replace github iframes with badges +- add migration guide + + +# 7.0.0-beta.1 +### Features +- remove unused stuff and change some names to simplify apis +- add @Outputs (show, isLastimage and isFirstImage) to catch navigation events like for modal-gallery +- merge the feature 'add a new method called update into GalleryService' from version 6.3.0 + +### Unit testing +- improve unit testing + +### Documentations +- rewrite navbar without bootstrap +- improve sidebar for both features and demo +- upgrade to the latest alpha version of angular-modal-gallery +- improve all carousel examples (updating input tables) +- improve colors and accessibility +- fix compatibility table in homepage +- update default values page + +### Chores +- update readme with a better layout (table of contents, images and so on) + + +# 7.0.0-alpha.2 +### Bugfixes +- fix responsive issue for carousel with fixed width +- fix wrong height of carousel's previews when hidden + +### Internal library changes +- upgrade to angular-cli 7 and Angular 7 +- upgrade to Typescript 3.1.1 +- add new MaxDirective to change max-height and max-width fully tested +- fix build internal docs with typedoc, using the latest @nect release to support typescript 3.1.1 + +### Demos +- add new demo angular-cli-6 to test this library also on angular 6 +- upgrade both angular-cli, universal and angular-cli-material to angular 7, angular-cli 7 and angular-material 7 + +### Documentations +- improve documentation website with a new Font +- improve performance with service workers, external fonts and optimized images and SVGs +- fix SEO issues about H1-H6 +- fix SEO issues about page titles and best practices about icons, themes, manifest.json and so on +- add Google Analytics +- update to Angular 7 and angular-cli 7 +- improve SSR and prerender +- remove unused libs like ng-bootstrap, jquery, popper and others +- first implementation of app-shell (still no working because of some incompatibilities with third party libs) +- add some examples of Carousel +- remove sidebar for all pages except for demo and features +- add accordion to demo sidebar, also saved in local storage + +### Unit testing +- restore code coverage for library's unit testing +- restore multiple browsers to run tests +- add unit testing for id-validator service and improve it forcing **integer** id values **> 0** **(BREAKING CHANGE)** + + +# 7.0.0-alpha.1 +### Features +- add (plain) carousel with previews +- new method in GalleryService called 'navigateGallery' +- gallery ids must be unique across the whole application **(BREAKING CHANGE)** +- requires rxjs >= 6 **(BREAKING CHANGE)** +- requires angular >= 6 **(BREAKING CHANGE)** +- change preview's sliding behaviour (simple and cleaner then before, taken from carousel's previews) **(BREAKING CHANGE)** + +### Internal library changes +- migrate to the official ng lib features in angular-cli >= 6.2 + +### Demos +- update main example with multiple pages +- upgrade all examples with multiple pages + +### Documentations +- new documentation website https://github.com/Ks89/angular-modal-gallery-2018-v7.github.io + +### CI +- upgrade CI config files to Node 10 + + +# 6.3.0 +### Features +- add a new method called 'update' into GalleryService to be able to update an image of the gallery calling this method, also when modal-gallery is already opened #161 + (requested and partially implemented by @smardine (see pull request https://github.com/Ks89/angular-modal-gallery/pull/162)) + + +# 6.2.3 +### Bugfixes +- when you press the back button, page scroll remains blocked, because the modal gallery isn't completely closed (reported by @srtab #159) + + +# 6.2.2 +### Bugfixes +- when you add images asynchronously with the modal gallery already opened, infinite sliding, the arrows, images and previews are managed in the wrong way (reported by @rezo-evodion #157) + + +# 6.2.2-beta.1 +### Bugfixes +- when you add images asynchronously with the modal gallery already opened, infinite sliding, the arrows, images and previews are managed in the wrong way (reported by @rezo-evodion #157) + + +# 6.2.1 +### Bugfixes +- if infinite sliding is enabled and there is only one image, navigation arrows should be hidden (reported by @rezo-evodion #156) + + +# 6.2.1 +### Bugfixes +- if infinite sliding is enabled and there is only one image, navigation arrows should be hidden (reported by @rezo-evodion #156) + + +# 6.2.0 +### Features +- add a new config property ('invertSwipe') inside CurrentImageConfig to invert swipe direction (requested by @anacatarinasousaaa #154) + + +# 6.1.2 +### Bugfixes +- fix readme.md on npmjs with the url to stackblitz v6, instead of v5 + + +# 6.1.1 +### Bugfixes +- modal image loses proportions on mobile when resized (caused by version 6.0.2 #145) fixed with #153 + + +# 6.1.0 +### Features +- add base64 support as image path #147 +- add new Image property to choose a file name for download #146 + +### Testing +- add other tests to cover some missing scenarios +- add unit testing for all new features + +### Demos +- add base64 demo to all examples +- add custom file name for download demo to all examples + + +# 6.0.2 +### Bugfixes +- fix current-image visibility on Microsoft Edge for Desktop #146 + + +# 6.0.2-beta.1 +### Bugfixes +- fix current-image visibility on Microsoft Edge for Desktop #146 + + +# 6.0.1 +### Bugfixes +- fix readme published on npmjs + + +# 6.0.0 +### Features +- id is now a mandatory input parameter (BREAKING CHANGE) +- **new package name `@ks89/angular-modal-gallery`** (to install use `npm i --save @ks89/angular-modal-gallery@next`) (BREAKING CHANGE) +- Support Angular Package Format specification v5 (BREAKING CHANGE) +- Remove Angular 4 support (BREAKING CHANGE) +- Add close method inside gallery.service (requested by @Enngage) +- Force side previews at the margins, because they was moving with current images of different sizes (rectangular) (requested by @Enngage) (BREAKING CHANGE) +- Add workaround to support SystemJS + AOT #142 - requested by @mlc-mlapis (**BREAKING CHANGE FOR ALL SYSTEMJS USERS**) +- Add full-screen button in FULL strategy +- Move loadingConfig, description and downloadble into CurrentImageConfig (BREAKING CHANGE) + +### Bugfixes +- Fix an issue when strictNullChecks and AOT are enabled together + +### Internal library changes +- Force AOT builds with all strict options in ng-packagr tsconfig file used in `npm run build:lib` +- Migrate to nwrl/nx 0.9.0 +- Migrate to ng-packagr 2 + +### Testing +- Update full-screen button +- Update for the new loadingConfig api +- Update unit testing with the new CurrentImageConfig + +### Chores +- New 6.0.0 logo red/orange + +### Docs +- Release [the new documentation website 6.0.0](https://ks89.github.io/angular-modal-gallery-2018-v6.github.io/) + +### Demos +- Add an example with Angular 5.x.x and angular-cli 1.7.x +- Update all examples to the new APIs +- Remove webpack example + + +# 6.0.0-beta.2 +### Features +- add close method inside gallery.service (requested by @Enngage) +- force side previews at the margins, because they was moving with current images of different sizes (rectangular) (requested by @Enngage) +- add workaround to support SystemJS + AOT #142 - requested by @mlc-mlapis (**BREAKING CHANGE FOR ALL SYSTEMJS USERS**) + +### Docs +- release documentation website beta.2 + +### Demos +- Update all examples with the usage of close method + + +# 6.0.0-beta.1 +### Docs +- release documentation website beta.1 + +### Demos +- Update all examples to Angular 6 (also universal) +- Add an example with Angular 5.x.x and angular-cli 1.7.x + + +# 6.0.0-alpha.4 +### Features +- add full-screen button in FULL strategy +- new 6.0.0 logo red/orange + +### Testing +- update full-screen button +- update for the new loadingConfig api + +### Bugfixes +- fix an issue when strictNullChecks and aot are enabled together + +### Internal library changes +- force AOT builds with all strict options in ng-packagr tsconfig file used in `npm run build:lib` + + +# 6.0.0-alpha.3 +### Features +- move loadingConfig, description and downloadble into CurrentImageConfig + +### Demos +- Update all examples + +### Testing +- Update unit testing with the new CurrentImageConfig + + +# 6.0.0-alpha.2 +### Features +- Description bottom margin in modal image is now 0px instead of 5px (BREAKING CHANGE) + +### Internal lib changes +- migrate to angular 6 +- migrate ru rxjs 6 +- migrate to angular-cli 6 + + +# 6.0.0-alpha.1 +### Features +- Support Angular Package Format specification v5 (BREAKING CHANGE) +- Remove Angular 4 support (BREAKING CHANGE) +- new package name `@ks89/angular-modal-gallery` (to install use `npm i --save @ks89/angular-modal-gallery@next`) + +### Internal lib changes +- migrate to nwrl/nx 0.9.0 +- migrate to ng-packagr 2 + +### Demos +- remove webpack example +- update all example + + +# 5.7.1 +### Bugfixes +- getDescriptionToDisplay is used in current-image.html also for titles. So, when strategy is ALWAYS_HIDDEN, + titles will be always ‘’. That’s wrong, because I should hide only descriptions not titles (useful for accessibility purposes)! + +### Examples +- update angular-cli-6 example to angular 6.0.0 final and angular-cli 6.0.0 final + +### Others +- add angular-modal-gallery 6.0.0 warning in README.md (release scheduled for May 2018) + + +# 5.7.0 +### Features +- Add optional param to disable click events on the current image #135 (@iss936) + + +# 5.6.0 +### Features +- add gallery.service to call modal-gallery methods without plain gallery. + In this way you are able to open modal gallery to an image by its index, without clicking on a thumb, but via Component's code. + This feature closes these two feature requests #127 (@pieterdegraeuwe) and #131 (@tobi-or-not-tobi) + +### Testing +- add unit testing for both component and service + +### CI +- improve CI configs + + +# 5.6.0-beta.1 +### Features +- add gallery.service to call modal-gallery methods without plain gallery. + In this way you are able to open modal gallery to an image by its index, without clicking on a thumb, but via Component's code. + This feature closes these two feature requests #127 (@pieterdegraeuwe) and #131 (@tobi-or-not-tobi) + + +# 5.5.1 +### Bugfixes +- Fix modal-gallery layout on small screens when there is one image in the array #136 (thanks to @pieterdegraeuwe) + + +# 5.5.0 +### Features +- add new spinners https://codepen.io/WebSonata/pen/bRaONB, https://codepen.io/nikhil8krishnan/pen/dMEzGx, https://codepen.io/devilishalchemist/pen/emOVYQ #117 + + +# 5.4.0 +### Features +- add background, text color, position, size and margin properties to Description interface #133 (requested by @tobi-or-not-tobi) +- add Angular 6 and angular-cli 6 experimental support + +### Demos +- new official example with angular-cli 6.0.0-beta.5 and angular 6.0.0-rc.0 + + +# 5.4.0-beta.3 +### Features +- add Angular 6 and angular-cli 6 experimental support + +### Bugfixes +- apply default values to description (added with both beta1 and beta2) #133 (reported by @tobi-or-not-tobi) + +### Demos +- new official example with angular-cli 6.0.0-beta.5 and angular 6.0.0-rc.0 + + +# 5.4.0-beta.2 +### Features +- flatten description's style property adding also other inputs #133 (requested by @tobi-or-not-tobi) + + +# 5.4.0-beta.1 +### Features +- add background, text color and margins properties to Description interface #133 (requested by @tobi-or-not-tobi) + + +# 5.3.0 +### Features +- official support @fortawesome/fontawesome 5 + +### Demos +- force AOT builds in all examples based on angular-cli also for `npm start` +- replace font-awesome 4.7.0 with fontawesome 5 in all examples (expect for webpack) +- update all examples based on the main demo + + +# 5.3.0-beta.1 +### Features +- official support @fortawesome/fontawesome 5 + +### Demos +- force AOT builds in all examples based on angular-cli also for `npm start` +- replace font-awesome 4.7.0 with fontawesome 5 in all examples (expect for webpack) +- update all examples based on the main demo + + +# 5.2.2 +### Bugfixes +- If I set previewsConfig.number with a value <= 0, I should restore the default number (=3) + + +# 5.2.1 +### Bugfixes +- If previews aren’t clickable, I should show a not-allowed mouse cursor + + +# 5.2.0 +### Features +- window on server side is undefined => add a workaround to fully support SSR #125 + +### Bugfixes +- update all examples with both before and after hooks in example B20 with font-awesome as requested by @matiishyn in #92 + + +# 5.2.0-beta.1 +### Features +- window on server side is undefined => add a workaround to fully support SSR #125 + + +# 5.1.0 +### Features +- support html image description (requested by @ckelkar) #123 + +### Bugfixes +- pass keyboardAction instead of clickAction for keyup event in current-image.component + + +# 5.1.0-beta.2 +### Bugfixes +- pass keyboardAction instead of clickAction for keyup event in current-image.component + + +# 5.1.0-beta.1 +### Features +- support html image description (requested by @ckelkar) #123 + + +# 5.0.1 +### Fix +- I forgot to publish README.md on npmjs :) + +### Chores +- update to 5.0.1 final in all examples + + +# 5.0.0 +### Features +- Rewrite SCSS/CSS layout in a more powerful way with **FLEXBOX** fixing some well known bugs #98 #37 (BREAKING CHANGE) +- Improve accessibility with ARIA #99 (BREAKING CHANGE) +- Remove Angular 2 support (for instance replace Renderer with Renderer2) #70 (BREAKING CHANGE) +- Update to Angular 5 #83 +- Partial support to Server-Side-Rendering (SSR) with Angular Universal (waiting for 'window' object on server side) #81 (BREAKING CHANGE) +- Support for IE11 using navigator.mssaveblob #39 +- new class Image API (with modal and plain inner objects) (BREAKNIG CHANGE) +- Improve modal layout with small previews and eventually also animations #48 (BREAKING CHANGE) +- Thumbnail size/more options #91 (BREAKNIG CHANGE) +- Completely rewrite "imagepointer feature" #49 (BREAKING CHANGE) +- Square thumbnails are now supported #76 (BREAKING CHANGE) +- Support configurable buttons with custom actions #79 and #92 (BREAKING CHANGE) +- Infinite sliding will be disabled by default #84 (BREAKING CHANGE) +- Click Outside will be enabled by default #85 (BREAKING CHANGE) +- New image descriptions with figcaptions +- remove Observable as input. I decided to switch to Image[] to simplify the sourcecode #105 (BREAKING CHANGE) +- Remove all deprecated APIs (both showDownloadButton and showExtUrlButton) +- prevent browser scrolling when modal gallery is opened + +### Performances +- Performance improvements with trackById and OnPush (BREAKING CHANGE) (Commit 3cb56435f0426c715ca442cd1e7a6a5cc222c3b9 and #103) +- add onpush strategy also to modal-gallery.component + +### Bugfixes +- Fix a bug on Microsoft Edge Desktop #108 + +### Chores +- add credits and licenses to all images, icons and so on +- test everything on IE11, Edge, iOS, Android...and what about iPhone X? +- add sonarcloud.io +- release the umd bundle on a CDN like unpkg.com (update: available [HERE](https://unpkg.com/angular-modal-gallery@5.0.0-beta.1/bundles/angular-modal-gallery.umd.min.js) ) + +### Demos +- Update systemjs example to 5.0.0 +- Update webpack example to 5.0.0 +- Update angular-cli example to 5.0.0 +- Add new universal example to use SSR +- Add new angular-cli-material example with Angular Material +- switch from plnkr.co to stackblitz.com +- Support "https://github.com/mgechev/angular-seed" #56 (it's also working with angular-modal-gallery >= 4.0.0) + +### Docs +- Add a MINIMAL migration guide from 4.x.x to 5.0.0 +- Update public documentation website to 5.0.0 +- Publish public documentation website on a private VPS (coming soon in a week) +- Update library documentation with typedocs to 5.0.0 +- add compodoc + +### Internal lib changes +- General refactoring reorganizing the structure of this project and splitting some components #42 (BREAKING CHANGE) +- Update unit testing to 5.0.0 +- choose which are the right entry points in package.json as described by angular package format 5 specifications + + +# 5.0.0-rc.3 +### Bugfixes +- full description is working again (broken since beta releases) + +### Others +- add PayPal donation button and prettier badge + + +# 5.0.0-rc.2 +### Features +- remove REFRESH button (BREAKING CHANGE) + +### Others +- update all official examples + + +# 5.0.0-rc.1 +### Bugfixes +- fix prod/aot build with strictNullChecks and add fullTemplateTypeCheck, preserveWhiteSpace, strictInjectionParameters, strictNullChecks to all examples. Reported by @Enngage #122 +- permit to remove images without to break previews +- loading spinner is working again. Also I updated all examples with new images (modal+thumb) to show in a better way spinners #120 + +### Internal library changes +- PlainImage and ModalImage should share only common things, instead of extending a class with all params. This is really confusing. + +### Unit testing +- complete unit testing + + +# 5.0.0-beta.2 +### Bugfixes +- when slideConfig doesn't contain the 'infinite' property should disable inifinte sliding +- fix accessibility bug in current-image when inifinte === true + +### Unit testing +- add unit tests for current-image and modal-gallery + + +# 5.0.0-beta.1 +### Features +- (requested by @Enngage) configure exturl button to navigate to an external url also in a new tab, instead of only in the current one #116 +- expose as public constants both default accessibility config, all button default configs and default size +- increase the maximum size of current modal image reducing useless spacing and margins + +### Bugfixes +- (thanks to @Enngage) current image should be centered also vertically + +### Unit testing +- add unit tests for background, previews, dots, loading spinner, plain-gallery + + +# 5.0.0-alpha.5 +### Features +- add accessibility features to plain-gallery +- improve PlainGalleryConfig.advanced adding the new 'additionalBackground' property **BREAKING CHANGE** + +### Bugfixes +- fix some small bugs everywhere, in particular in upper-buttons.component + +### Internal library changes +- switch to Nwrl nx workspace +- improve scss with sass-lint and ts files with prettier +- add both e2e and unit tests support with Nwrl nx workspace +- move `getIndex` to utils +- general refactoring to import from model/index and utils/index + +### CI +- add sonarcloud.io analysys +- fix and update all CI config files +- add Jenkins 2 (both local macOS and remote config on a private vps) + +### Docs +- add Typedoc also for interfaces, enums, classes, directives and so on + +### Others +- add prettier config with both .prettierignore and .prettierrc.json +- add sass-lint config with .sass-lint.yml + +### Unit testing +- add tests for all services +- add tests for all directive except for `keyboard-navigation.directive` +- add test for `upper-buttons.component` + + +# 5.0.0-alpha.4 +### Features +- change all "Size" objects using strings to be able to set also 'auto' (apply the same fix to ksSize) +- update all default sizes to support rectangle images (not only squared) +- initial implementation of plain gallery with different layouts (row, column, grid) #91 +- re-implement 'image pointer' feature #49 +- add square thumbnails feature #76 with an API to choose between and for thumbs +- new class Image API (with modal and plain inner objects) +- add official examples of plain gallery (row with breakConfig, column with breakConfig, grid, row with image pointer, column with image pointer, custom row of images with description) +- define APIs for plain gallery: + ``` + PlainGalleryConfig = { + strategy: ENUM of type PlainGalleryStrategy (ROW, COLUM, GRID, CUSTOM) + layout: // PlainGalleryLayout type that can be either LineLayout, GridLayout or AdvancedLayout + advanced?: AdvancedConfig { + aTags: boolean // images will be shown as tags with background instead of + } + } + + Size = { + width: string, // it can be '50px', percentage, 'auto' and so on + height: string // the same for width + } + + BreakConfig = { + length: number, // number of images to show + wrap: boolean // refers to the [wrap property of flex-box](https://css-tricks.com/snippets/css/a-guide-to-flexbox/#article-header-id-4) + } + + LineLayout = { + breakConfig: BreakConfig; + justify: string; string // refers to the [justify property of flex-box](https://css-tricks.com/snippets/css/a-guide-to-flexbox/#article-header-id-6) + size: Size; + } + + GridLayout = { + breakConfig: BreakConfig; + size: Size; + } + + AdvancedLayout = { + modalOpenerByIndex: number, // index of the image to open + hideDefaultPlainGallery: boolean // set to true to hide the defaut gallery (prevent multiple plain galleries) + } + ``` + +### Bugfixes +- central image now shown on Microsoft Edge Desktop #108 +- fix click-outside.directive on both Edge, IE and Firefox, changing event.toElement to event.target +- fix typedoc support to build the documentation + +### Chores +- add license attributions (in README and in the main angular-cli example) to both icons and spinners authors +- add CI scripts (TravisCI, AppVeyor, CircleCI) +- badges in README.md + +### Demos +- update all demos to alpha 4 +- refactor systemjs demo moving html in an external file + +### Docs +- Complete library documentation with typedocs + + +# 5.0.0-alpha.3 +### Features +- prevent browser scrolling when modal gallery is opened (implemented thanks to this `hide scrollbar to fix right margin (thanks to @Enngage)`) + +### Bugfixes +- hide scrollbar to fix right margin (thanks to @Enngage) +- restore isFirstImage and isLastImage to show previews again after reached the boundaries +- add height:auto to previews to display also rectangular images + + +# 5.0.0-alpha.2 +### Bug fixes +- emit show output event every time the current image changes +- fix to add images updating the internal model (this bug is caused by OnPush strategy into modal-gallery.component) + +### Chores +- upgrade CI config files to 5.0.0-alpha.2 + + +# 5.0.0-alpha.1 +### Features +- Rewrite SCSS/CSS layout with **FLEXBOX** fixing some well known bugs #98 #37 (**BREAKING CHANGE**) +- Improve accessibility with ARIA #99 (**BREAKING CHANGE**) +- Update to Angular 5 #83 +- Initial support to Server-Side-Rendering (SSR) with Angular Universal #81 (**BREAKING CHANGE**) (**PARTIALLY IMPLEMENTED** - I still have a small issue) +- Add support for IE11 using navigator.mssaveblob #39 +- Improve modal layout with small previews and eventually also animations #48 (**BREAKING CHANGE**) +- Support configurable buttons with custom actions #79 and #92 (**BREAKING CHANGE**) +- Support "https://github.com/mgechev/angular-seed" #56 (it's also working with angular-modal-gallery >= 4.0.0) +- Infinite sliding will be disabled by default #84 (**BREAKING CHANGE**) +- Click Outside will be enabled by default #85 (**BREAKING CHANGE**) +- Which is the best place for image description? Think about it. [I decided to use html's tag figurecaption ] [DONE - This feature will be released with #98] (**BREAKING CHANGE**) +- Remove all deprecated APIs (both showDownloadButton and showExtUrlButton) (**BREAKING CHANGE**) + +### Performances +- Performance improvements with trackById and OnPush (**BREAKING CHANGE**) (Commit 3cb56435f0426c715ca442cd1e7a6a5cc222c3b9 and #103) +- add onpush strategy also to modal-gallery.component + +### Demos +- Update systemjs example to 5.0.0 +- Update webpack example to 5.0.0 +- Update angular-cli example to 5.0.0 +- Add new plunkr examples for both 4.x.x and 5.x.x +- Add new universal example to experiment Server-Side Rendering with Angular Universal + +### Docs +- Update library documentation with typedocs to 5.0.0 + +### Internal library changes +- Remove Angular 2 support (for instance replace Renderer with Renderer2) #70 (**BREAKING CHANGE**) +- General refactoring reorganizing the structure of this project and splitting some components #42 (**BREAKING CHANGE**) +- remove Observable as input. I decided to switch to Image[] to simplify the sourcecode #105 (**BREAKING CHANGE**) +- choose which are the right entry points in package.json as described by angular package format 5 specifications + + +# 4.0.1 +### Chores +- Add LICENSE and other .md files to the released bundle + + +# 4.0.0 +### Features +- Angular 5.x.x support #83 #101 +- [Angular Package Format v4.0]( https://goo.gl/AMOU5G) support (very important feature) #100 + +### Bugfixes +- remove dependencies and devDependencies from /angular-modal-gallery/package.json #101 + +### BREAKING CHANGES +- **Angular 2 is no longer officially supported**, please upgrade to Angular >= 4 +- SystemJs users have to change their `systemjs.config.js` from +``` +let map = { + ... + 'angular-modal-gallery' : 'node_modules/angular-modal-gallery/dist/bundles', + ... + }; +``` + +to: +``` +let map = { + ... + 'angular-modal-gallery' : 'node_modules/angular-modal-gallery/bundles', + ... + }; +``` + +This is required by [Angular Package Format v4.0]( https://goo.gl/AMOU5G) specifications. + +A special thanks to [maxkorz](https://github.com/maxkorz) for the support. + + +# 4.0.0-rc.2 +### Bugfixes +- remove dependencies and devDependencies from /angular-modal-gallery/package.json #101 + +See 4.0.0-rc.1 for other info. + + +# 4.0.0-rc.1 +### Features +- Angular 5.x.x support #83 #101 +- [Angular Package Format v4.0]( https://goo.gl/AMOU5G) support (very important feature) #100 + +### BREAKING CHANGES +- SystemJs users have to change their `systemjs.config.js` from +``` +let map = { + ... + 'angular-modal-gallery' : 'node_modules/angular-modal-gallery/dist/bundles', + ... + }; +``` + +to: +``` +let map = { + ... + 'angular-modal-gallery' : 'node_modules/angular-modal-gallery/bundles', + ... + }; +``` + +This is required by [Angular Package Format v4.0]( https://goo.gl/AMOU5G) specifications. + + + +# 3.3.5 +### Chores +- Update FAQ with question "Error: No provider for KeyboardService!" #96 + +### Docs +- [DOC] fix wrong introduction in demo/no-infinite-sliding #97 +- [DOC] fix wrong introduction in demo/keyboard-config #93 + + +# 3.3.4 +### Chores +- Update official webpack demo to bootstrap 4 beta #87 +- refactoring and cleanup + tslint improved + ci improved #88 +- Update docs + add faqs + create templates for github #75 +- update to circleci 2.0 and add circleci 2.0 also to the doc website #78 +- update all dependencies +- fix config for all CIs + +### Docs +- Fix documentation website to be able to navigate to inner routes directly #86 + + +# 3.3.3 +### Bug fixes +- Fix for version 3.3.2 (broken) + + +# 3.3.2 +### Internal library changes +- Revert refactoring of 3.3.1 + + +# 3.3.1 +### Internal library changes +- Small refactoring +- #73 Trying to fix again "ERROR in Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function ..." + + +# 3.3.0 +### New features +- #41 KeyboardService should be capable to receive an object with an array of shortcuts from outside to configure Mousetrap. This is available as Global configuration of the Root Module. + +### Bug fixes +- #73 Fix again "ERROR in Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function ..." + + +# 3.2.3 +Note: **revert version 3.2.2** + +### Bug fixes +- #73 Fix again with a different approach this error: "ERROR in Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function ..." + + +# 3.2.2 +### Bug fixes +- #73 Fix: "ERROR in Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function ..." + + +# 3.2.1 +- all dependencies updated +- #71 'ButtonsConfig' was not found in './modal-gallery.component' (bug of angular-cli -> I used a temporary workaround) + + +# 3.2.0 +### New features +- #62 add 'alt' attribute to all img tags +- #45 Both at the beginning and at the end, side arrows should be hidden +- #44 Infinite sliding (configurable) + +### Docs +- official documentation updated [HERE](https://ks89.github.io/angular-modal-gallery.github.io/). + +### Demos +- all demos updated + +### Internal library changes +- #66 improve unit testing with swipe events + + +# 3.1.1 +- fix error in README.md + + +# 3.1.0 +### New features +- #43 `ButtonsConfig` object to configure button's visibility +- #57 `KeyboardConfig` object to customize keyboard's actions (replacing `esc`, `left arrow`, `right arrow`, with other keys) +- #40 new @Input to enable Click outside Directive to close modal-gallery clicking on the semi-transparent background +- #67 Angular 2 is still supported + +### Docs +- official documentation updated [HERE](https://ks89.github.io/angular-modal-gallery.github.io/). + +### Demos +- #68 angular-cli demo updated to the latest release of angular-cli and with 3 new live examples for angular-modal-gallery 3.1.0 +- #68 webpack and systemjs demos updated with 3 new live examples for angular-modal-gallery 3.1.0 + +### Bug fixes +- #64 hasData event emitted multiple time while initializing the component +- #65 wrong result into ImageModalEvent when clicking left arrow button + +### Chores +- #63 Add minimum IE version supported by this library (IE 11) + +### Internal library changes +- #14 unit testing +- #59 basic tslint config for angular-modal-gallery lib +- #69 improve CIs config for unit testing (adding also coveralls ad codeclimate's reports) +- #60 build env with npm>=5.0.0 and node>=8.0.0 +- #61 replace elementref with renderer to prepare this project to angular-universal (still not supported, but this is the first step) + + +# 3.0.2 +### Chores +- Angular 4.1.0 #50 +- dependencies updated + +### Docs +- Improved official documentation website (scroll bug fixed #47 and improved responsiveness #38) +- dependencies updated + +### Demos +- tslint 5 in all demos #54 +- Official demos: IE performance issue with debug mode #51 +- dependencies updated + + +# 3.0.1 + +### Bug fixes +- readme fix wrong link (exactly the same library of 3.0.0) + + +# 3.0.0 +**THIS VERSION IS A VERY BIG RELEASE. IF YOU WANT TO MIGRATE FROM 2.x.x to 3.0.0 PLEASE CHECK THE OFFICIAL DOCUMENTATION [HERE](https://ks89.github.io/angular-modal-gallery.github.io/)** + +### Breaking changes +- `hammerjs` and `mousetrap` are mandatory libraries (install they with `npm install --save hammerjs mousetrap`). +- `(cancelEvent)="myfunction($event)"` replaced by `(close)="myfunction($event)"`. +- `` replaced by ``. +- You have to init input images with an `Array` or an `Observable>` as explained [HERE](https://ks89.github.io/angular-modal-gallery.github.io/). + +### New features +- swipe support for mobile devices with touch-screen. +- optional thumbnail (if you provide only the bigger version, this library will scale down your image). +- downloadable images with both a button and keyboard shortcuts. You have to set `[downloadable]="true"` and `[showExtUrlButton]="true"`. +- optional external url button. You have to set `[showExtUrlButton]="true"`. +- fully configurable description using `[description]="yourDescriptionInterfaceVariable"` passing `Description` interface with `customFullDescription`, `imageText`, `numberSeparator`, `beforeTextDescription`. +If you pass `customFullDescription`, all the others will be overwritten. +- new output events available: `(hasData)="myfunction($event)"`, `(show)="myfunction($event)"`, `(firstImage)="myfunction($event)"`, `(lastImage)="myfunction($event)"`. +- new classes/enums exported and available to all users: `Image`, `Action`, `ImageModalEvent`, `Description`. + - `Image` is the input class with the following (mandatory) string properties: `thumb`, `img`, `description` and `extUrl`. + - `Action` is the enum that specify the origin of the action. It can be `NORMAL`, `CLICK`, `KEYBOARD`, `SWIPE`, `LOAD`. + - `ImageModalEvent` is the output class emitted as payload of an event. It contains both an `Action` and a result (boolean or number). + - `Description` is the description interface with `customFullDescription`, `imageText`, `numberSeparator`, `beforeTextDescription`. +- `myfunction(event: ImageModalEvent)` can use the Action name as a string with this syntax: `Action[event.action]`, because I exported `Action` enum to all users. +- support for `ModalGalleryModule.forRoot()` to import this module inside your root module (as recommended by Angular). For a child NgModule, you must use simply `ModalGalleryModule`. + +### Docs +- official documentation (bootstrap-like :)) with live demo, migration guide and features showcase [HERE](https://ks89.github.io/angular-modal-gallery.github.io/). + +### Demos +- new angular-cli official demo inside `demo/angular-cli` +- official systemjs demo updated to 0.20.x with some breaking changes. +- official webpack demo updated to Angular 4 RC :) + +### Internal library changes +- big refactoring splitting the sourcecode and using directives, services, sub-components and so on. +- new library structure thanks to [cankayacan](https://github.com/cankayacan/ngx-library-starter). +- css rewritten using scss and a dedicated rollup's plugin. + +### Bug fixes +- lot of bug fixes everywhere (.ts, .css but also for mobile devices) :). + + +# 2.0.2 +### Developers and users of this library +- description is now displayed correctly (issue #21) +- documentation improvements + +### Myself and other contributor of this project +- npm scripts improved with `ncp` and `mkdirp` +- added `prebuild` and `postbuild` scripts +- building process improved to prevent some errors + + +# 2.0.0 + 2.0.1 +- Stability improvements + bugfixes +- CI support improved but still WIP +- documentation improvements + + +# alpha.1 +- first release based on `vimalavinisha/angular2-image-popup` +- AOT support +- Angular 4 compatibility +- New build system with rollup js +- Experimental CI support +- Two official demo applications (systemjs + webpack 2) +- Live demo with webpack available at https://ks89.github.io/angular-modal-gallery/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..0995e64e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,98 @@ +Sometimes, shy developers have wonderful ideas. So don't be shy and open an issue! :) + +If you want to help me, modify the source code, but **before to create a pull request, follow these steps** + +**Attention! This is really important** +Every time you'll run `npm install` inside an example's folder, you must rebuild all with `npm run build:all` + +# A. Cleanup and initialization +1. `npm install -g lite-server @angular/cli@latest` +2. remove all `node_modules` and temp folders with compiled files (if necessary) +3. `npm install` (from the root of this project) +4. `npm run clean:all` +5. `cd examples/angular-cli-19` +6. `npm install` +7. `cd ../..` +8. `cd examples/universal` +9. `npm install` +10. `cd ../..` +11. `cd examples/angular-cli-material` +12. `npm install` +13. `cd ../..` +14. `npm run build:all` +15. `npm test` + +# B. Run main example +1. `npm start` => if everything is ok (also in browser's console), kill the process and go to the next step +2. `npm run build:main:dev` +3. `cd dist/angular-modal-gallery/browser && lite-server` => if everything is ok (also in browser's console), kill the process and go to the next step +4. `cd ../../..` +5. `npm run build:main:prod` +6. `cd dist/angular-modal-gallery/browser && lite-server` => if everything is ok (also in browser's console), kill the process and go to the next step +7. `cd ../../../../..` + +# C. Run angular-cli-19 example +1. `cd examples/angular-cli-19` +2. `npm start` => if everything is ok (also in browser's console), kill the process and go to the next step +3. `npm run build:dev` +4. `cd dist/angular-cli/browser && lite-server` => if everything is ok (also in browser's console), kill the process and go to the next step +5. `cd ../../..` +6. `npm run build:prod` +7. `cd dist/angular-cli/browser && lite-server` => if everything is ok (also in browser's console), kill the process and go to the next step +8. `cd ../../../../..` + +# D. Run angular-cli-material example +1. `cd examples/angular-cli-material` +2. `npm start` => if everything is ok (also in browser's console), kill the process and go to the next step +3. `npm run build:dev` +4. `cd dist/angular-cli/browser && lite-server` => if everything is ok (also in browser's console), kill the process and go to the next step +5. `cd ../../..` +6. `npm run build:prod` +7. `cd dist/angular-cli/browser && lite-server` => if everything is ok (also in browser's console), kill the process and go to the next step +8. `cd ../../../../..` + +# E. Run universal example +1. `cd examples/universal` +2. `npm start` => if everything is ok (also in browser's console), kill the process and go to the next step +3. `npm run build:dev` +4. `npm run serve:ssr` => if everything is ok (also in browser's console), kill the process and go to the next step +5. `npm run build:prod` +6. `npm run serve:ssr` => if everything is ok (also in browser's console), kill the process and go to the next step +7. `cd ../..` + +# H. Create your pull request +1. **If it is ok, create your pull request specifying all the details** + +
+
+ +# Only for the author @Ks89 - How to publish this on npm? + +## Stable releases (@latest) +1. `cd projects/ks89/angular-modal-gallery` +2. `npm version patch` (x.x.1) or `npm version minor` (x.1.0) or `npm version major` (5.x.x) +3. `cd ../..` +4. `npm run clean:all` +5. `npm run build:lib` +6. `cd @ks89/angular-modal-gallery` +7. `npm publish` +8. `git push origin master` +9. `git push origin vx.x.x` <-- tag name created by npm version (for instance v5.0.1) + +## Beta and RC releases (@beta) +1. `cd projects/ks89/angular-modal-gallery` +2. Manually change the version of `./package.json` with either this format `x.x.x-beta.x` or `x.x.x-rc.x` (also respect semver!) +3. `cd ../..` +4. `npm run clean:all` +5. `npm run build:lib` +6. `cd @ks89/angular-modal-gallery` +7. `npm publish --tag beta` + +## Alpha releases (@next) +1. `cd projects/ks89/angular-modal-gallery` +2. Manually change the version of `./package.json` with this format `x.x.x-alpha.x` (also respect semver!) +3. `cd ../..` +4. `npm run clean:all` +5. `npm run build:lib` +6. `cd @ks89/angular-modal-gallery` +7. `npm publish --tag next` diff --git a/LICENSE b/LICENSE index bb5a8b75..c385cd21 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,6 @@ The MIT License (MIT) +Copyright (c) 2017-2024 Stefano Cappa (Ks89) Copyright (c) 2016 vimalavinisha Permission is hereby granted, free of charge, to any person obtaining a copy @@ -14,7 +15,7 @@ copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE diff --git a/README.md b/README.md index effa5292..d09889e6 100644 --- a/README.md +++ b/README.md @@ -1,72 +1,295 @@ -Angular2 image popup -========= - -The sources for this package are in (https://github.com/vimalavinisha/angular2-image-popup) repo. Please file issues and pull requests against this repo. - -## Demo Output - ![angular2-image-popup](https://cloud.githubusercontent.com/assets/11042288/16330239/78a57df6-3a05-11e6-98b9-7414c0eaf794.png) - ![popup](https://cloud.githubusercontent.com/assets/11042288/16330244/861f3cc4-3a05-11e6-8757-7baf315eda8c.png) -##Usage - node install - npm install angular2-image-popup - bower install - bower install image-popup -###1.In index.html page include following css - - - -###2.component file use like below - import {Component} from '@angular/core'; - import {ImageModal} from '../directives/angular2-image-popup/image-modal-popup'; - @Component({ - selector : 'my-app', - directives: [ImageModal], - template: ` -

Example - Default

-

you can directly access "ImageModel" directive for both listing thumbnails and popup images

- - -

Example with thumbnail pointers

-

you can list images in your file and then calling "ImageModel" directive to show images on popup only

-
- -
-
- -
- ` - }) - export class AppComponent { - openModalWindow:boolean=false; - imagePointer:number; - images = [ - { thumb: './app/assets/images/gallery/thumbs/img1.jpg', img: './app/assets/images/gallery/img1.jpg', description: 'Image 1' }, - { thumb: './app/assets/images/gallery/thumbs/img2.jpg', img: './app/assets/images/gallery/img2.jpg', description: 'Image 2' }, - { thumb: './app/assets/images/gallery/thumbs/img3.jpg', img: './app/assets/images/gallery/img3.jpg', description: 'Image 3' }, - { thumb: './app/assets/images/gallery/thumbs/img4.jpg', img: './app/assets/images/gallery/img4.jpg', description: 'Image 4' }, - { thumb: './app/assets/images/gallery/thumbs/img5.jpg', img: './app/assets/images/gallery/img5.jpg', description: 'Image 5' } - ]; - constructor() { - - } - OpenImageModel(imageSrc,images) { - //alert('OpenImages'); - var imageModalPointer; - for (var i = 0; i < images.length; i++) { - if (imageSrc === images[i].img) { - imageModalPointer = i; - console.log('jhhl',i); - break; - } - } - this.openModalWindow = true; - this.images = images; - this.imagePointer = imageModalPointer; - } - cancelImageModel() { - this.openModalWindow = false; - } - } +

+
+ @ks89/angular-modal-gallery +
+
+@ks89/angular-modal-gallery +
+

+ +

@ks89/angular-modal-gallery is an Angular library (SSR compatible) to create image galleries.

+
+

+Despite its name, this library is more than for modal galleries, because I'm introducing new features every major release. In fact, It's composed by 3 main parts:

+ +

@ks89/angular-modal-gallery supports also keyboard shortcuts, swipe gestures and mouse events.

+
+ +

+ + npm@latest + + + npm@beta + + + npm@next + +

+

+ Downloads/week + Downloads/month + Downloads/year +

+

+ Github Actions CI result +

+

+ Known Vulnerabilities + david-dm Dependencies + FOSSA Status + code style: prettier +

+

+ Coveralls Coverage +

+

+ AngularStyleGuide +

+

+ Donate + NPMLicense + Semver +

+ +
+Do you like @ks89/angular-modal-gallery? Please, add a :star: to support this library +
+ +
+ +## Table of Contents + +1. **[Main parts](#rocket-main-parts-rocket)** +2. **[Features](#boom-features-boom)** +3. **[Installation](#package-installation-package)** +4. **[OFFICIAL DOCUMENTATION](#book-documentation-book)** +5. **[Choose the version](#warning-choose-the-version-warning)** +6. **[News](#fire-news-fire)** +7. **[FAQS](#question-faqs-question)** +8. **[Contributing](#computer-contributing-computer)** +9. **[A big 'thank you' to](#sparkling_heart-a-big-thank-you-to-sparkling_heart)** +10. **[License](#copyright-license-copyright)** + +
+ +## :rocket: Main parts :rocket: + +### Carousel + +

+ Carousel full width +

+

+ Carousel fixed width +

+ +### Modal Gallery + +

+ Modal gallery +

+

+ Modal gallery with buttons +

+ +### Plain Gallery + +

+ Plain gallery row +

+ +

+ Plain gallery column +     + Plain gallery grid +

+ +
+ +## :boom: Features :boom: +- Angular Module to import this library +- compliant to Angular Package Format specifications and recommendations +- **use [Semantic versioning 2.0.0](http://semver.org/)** also known as 'semver' +- official examples with `angular-cli`, `angular-cli + material` and `angular-universal` [HERE](https://github.com/Ks89/angular-modal-gallery/tree/master/examples) +- unit testing with high % coverage +- **Server Side Rendering** support with angular-universal +- Web Accessibility features, like ARIA support and [toptal.com](https://www.toptal.com/designers/colorfilter) criteria (tested with `Sim Daltonism` for macOS) +- image **download** with buttons or keyboard shortcuts +- fully configurable default buttons to either close, download, navigate to an external url or delete images and so on +- support custom buttons with both pre and after hooks +- **click outside feature** to close the modal gallery clicking on the background +- configurable **plain gallery** +- configurable **carousel** +- configurable side-previews (visible only on bigger screen) +- configurable dots navigation (visible only on bigger screen) +- configurable previews (visible only on bigger screen) +- and many more... (check the official documentation [HERE](https://ks89.github.io/angular-modal-gallery-2024-v13.github.io/)) + +
+ +## :package: Installation :package: + +- `npm install --save @ks89/angular-modal-gallery` +- `npm install --save @angular/cdk` + +From version @ks89/angular-modal-gallery >= 5.0.0, **font-awesome isn't a mandatory dependency**. +You can use all default features without font-awesome. For more info, check official [documentation website](https://ks89.github.io/angular-modal-gallery-2024-v13.github.io/). +From version @ks89/angular-modal-gallery >= 11.0.0, **mousetrap and hammerjs have been removed as dependencies**. + +
+ +## :book: **Documentation** :book: + +*Image loading could be slow, because this website is hosted on Github pages* + +[OFFICIAL DOCUMENTATION WEBSITE](https://ks89.github.io/angular-modal-gallery-2024-v13.github.io/) + +
+ +## :warning: Choose the right version :warning: + +| | @ks89/angular-modal-gallery | font-awesome | +|------------|:---------------------------:| :---: | +| AngularJS | NOT SUPPORTED | | +| Angular 2 | = 3.3.5 | >= 4.0.0 | +| Angular 4 | = 5.7.1 | optional | +| Angular 5 | = 6.3.0 | optional | +| Angular 6 | = 7.2.7 | optional | +| Angular 7 | = 7.2.7 | optional | +| Angular 8 | = 7.2.7 | optional | +| Angular 9 | = 7.2.7 | optional | +| Angular 10 | = 7.2.7 | optional | +| Angular 11 | = 7.2.7 | optional | +| Angular 12 | = 8.0.1 | optional | +| Angular 13 | = 9.1.0 | optional | +| Angular 14 | = 9.1.0 | optional | +| Angular 15 | = 10.0.1 | optional | +| Angular 16 | = 11.1.1 | optional | +| Angular 17 | = 11.1.1 | optional | +| Angular 18 | = 12.0.0 | optional | +| Angular 19 | >= 13.0.0 | optional | + +
+ +## :fire: News :fire: + +**More than 100 releases in two years**, and more to come... :) + +- 22/12/2024 - 13.0.0 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 31/05/2024 - 12.0.0 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 31/01/2024 - 11.1.2 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 09/12/2023 - 11.1.1 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 08/16/2023 - 11.1.0 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 08/06/2023 - 11.1.0-rc.1 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 07/08/2023 - 11.0.0 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 06/01/2023 - 11.0.0-rc.1 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 11/18/2022 - 10.0.1 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 11/17/2022 - 10.0.0 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 08/03/2022 - 10.0.0-rc.1 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 05/10/2022 - 9.1.0 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 04/23/2022 - 9.1.0-beta.2 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 04/14/2022 - 9.1.0-beta.1 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 11/15/2021 - 9.0.1 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 11/06/2021 - 9.0.0 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 09/27/2021 - 8.0.1 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 07/10/2021 - 8.0.0 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- - ... (many beta 8.x.x versions) +- 12/05/2020 - 7.2.7 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- - ... (many minor 7.x.x versions) +- 12/06/2018 - 7.0.0 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- 10/11/2018 - 6.3.0 - angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- ... (many minor 6.x.x versions) +- 06/10/2018 - 6.0.0 - @ks89/angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- ... (many minor 5.x.x versions) +- 02/27/2018 - 5.0.0 - angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- ... (many minor 4.x.x versions) +- 11/05/2017 - 4.0.0 - angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- ... (many minor 3.x.x versions) +- 03/20/2017 - 3.0.0 - angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) +- ... (many minor 2.x.x versions) +- 01/29/2017 - 2.0.0 - angular-modal-gallery - [HERE](https://github.com/Ks89/angular-modal-gallery/releases) + +
+ +## :question: FAQS :question: + +1. Question: **How can I remove images using DELETE button without issues?**
+ **Answer**: **You cannot change the input image array. Instead, you should reassign it with a newer array** without the deleted element. + In other words, **you must think in a functional way**, without changing the input array of images. + For more information check this official demo [HERE](https://ks89.github.io/angular-modal-gallery-2024-v13.github.io/demo/buttons-strategies). + +
+ +## :computer: Contributing :computer: + +Check `CONTRIBUTING.md` in this repository. +To understand how to contribute to an open source project, [HERE](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github) you can find useful information. + +When you create a pull request, please, format your code to be consistent with the existing code. I suggest to use [WebStorm](https://www.jetbrains.com/webstorm/) as IDE and when you commit don't use a third party software, but the official command line `git`. +In this way, [prettier](https://prettier.io/) will run using my configuration, and it will auto-format the code. If it fails, add files with `git add .` again and retry. + +
+ +## :sparkling_heart: A big thank you to :sparkling_heart: + +##### all authors of icons used in this library: +- Icons made by Smartline from www.flaticon.com is licensed by CC 3.0 BY +- Icons made by Dave Gandy from www.flaticon.com is licensed by CC 3.0 BY +- Icons made by Freepik from www.flaticon.com is licensed by CC 3.0 BY +- Icons made by Those Icons from www.flaticon.com is licensed by CC 3.0 BY +- Icons made by Gregor Cresnar from www.flaticon.com is licensed by CC 3.0 BY +- Icons made by Smashicons from www.flaticon.com is licensed by CC 3.0 BY +- Icons made by Dario Ferrando from www.flaticon.com is licensed by CC 3.0 BY + +##### all authors of spinners used in this library: +- Luke Haas (@lukehaas) - lukehaas/css-loaders +- Martin van Driel (@martinvd) - martinvd example on codepen.io +- Devilish Alchemist - devilishalchemist example on codepen.io +- Nikhil Krishnan - nikhil8krishnan example on codepen.io +- Anastasiya Kuligina - Anastasiya Kuligina example on codepen.io + +
+ +## :copyright: License :copyright: + +The MIT License (MIT) + +Copyright (c) 2017-2024 Stefano Cappa (Ks89) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +
+ +If you like my projects you can do a free donation here [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/stefanocappa) + + +## FOSSA report + +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FKs89%2Fangular-modal-gallery.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FKs89%2Fangular-modal-gallery?ref=badge_large) + +
+ +**Created by Stefano Cappa** + +**[⬆ back to top](#table-of-contents)** diff --git a/SECURITY.MD b/SECURITY.MD new file mode 100644 index 00000000..a0e3ae72 --- /dev/null +++ b/SECURITY.MD @@ -0,0 +1,25 @@ +# Security Policy + +## Supported Versions + +Only these versions are supported with security updates: + +| Version | Supported | +|---------|--------------------| +| 1.x.x | :x: | +| 2.x.x | :x: | +| 3.x.x | :x: | +| 4.x.x | :x: | +| 5.x.x | :x: | +| 6.x.x | :x: | +| 7.x.x | :x: | +| 8.x.x | :x: | +| 9.x.x | :x: | +| 10.x.x | :x: | +| 11.x.x | :x: | +| 12.x.x | :x: | +| 13.x.x | :white_check_mark: | + +## Reporting a Vulnerability + +To report a vulnerability, please don't open public issues, but email me privately. diff --git a/angular.json b/angular.json new file mode 100644 index 00000000..3652fc38 --- /dev/null +++ b/angular.json @@ -0,0 +1,151 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "angular-modal-gallery": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss", + "standalone": false + }, + "@schematics/angular:directive": { + "standalone": false + }, + "@schematics/angular:pipe": { + "standalone": false + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "ks", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:application", + "options": { + "outputPath": "dist/angular-modal-gallery", + "index": "src/index.html", + "browser": "src/main.ts", + "polyfills": [ + "zone.js" + ], + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "src/favicon.png", + "src/assets", + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "2MB", + "maximumError": "5MB" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "6kb", + "maximumError": "10kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-modal-gallery:build:production" + }, + "development": { + "buildTarget": "angular-modal-gallery:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n" + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "polyfills": [ + "zone.js", + "zone.js/testing" + ], + "tsConfig": "tsconfig.spec.json", + "inlineStyleLanguage": "scss", + "assets": [ + "src/favicon.png", + "src/assets", + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [] + } + } + } + }, + "@ks89/angular-modal-gallery": { + "projectType": "library", + "root": "projects/ks89/angular-modal-gallery", + "sourceRoot": "projects/ks89/angular-modal-gallery/src", + "prefix": "ks", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:ng-packagr", + "options": { + "project": "projects/ks89/angular-modal-gallery/ng-package.json" + }, + "configurations": { + "production": { + "tsConfig": "projects/ks89/angular-modal-gallery/tsconfig.lib.prod.json" + }, + "development": { + "tsConfig": "projects/ks89/angular-modal-gallery/tsconfig.lib.json" + } + }, + "defaultConfiguration": "production" + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "karmaConfig": "projects/ks89/angular-modal-gallery/karma.conf.js", + "codeCoverage": true, + "tsConfig": "projects/ks89/angular-modal-gallery/tsconfig.spec.json", + "polyfills": [ + "zone.js", + "zone.js/testing" + ] + } + } + } + } + }, + "cli": { + "analytics": false + } +} diff --git a/app/app.component.js b/app/app.component.js deleted file mode 100644 index f2e9c04f..00000000 --- a/app/app.component.js +++ /dev/null @@ -1,63 +0,0 @@ -/* - * @author Vimala A - */ -System.register(['@angular/core'], function(exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; - }; - var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); - }; - var core_1; - var AppComponent; - return { - setters:[ - function (core_1_1) { - core_1 = core_1_1; - }], - execute: function() { - AppComponent = (function () { - function AppComponent() { - this.openModalWindow = false; - this.images = [ - { thumb: './app/assets/images/gallery/thumbs/img1.jpg', img: './app/assets/images/gallery/img1.jpg', description: 'Image 1' }, - { thumb: './app/assets/images/gallery/thumbs/img2.jpg', img: './app/assets/images/gallery/img2.jpg', description: 'Image 2' }, - { thumb: './app/assets/images/gallery/thumbs/img3.jpg', img: './app/assets/images/gallery/img3.jpg', description: 'Image 3' }, - { thumb: './app/assets/images/gallery/thumbs/img4.jpg', img: './app/assets/images/gallery/img4.jpg', description: 'Image 4' }, - { thumb: './app/assets/images/gallery/thumbs/img5.jpg', img: './app/assets/images/gallery/img5.jpg', description: 'Image 5' } - ]; - } - AppComponent.prototype.OpenImageModel = function (imageSrc, images) { - var imageModalPointer; - for (var i = 0; i < images.length; i++) { - if (imageSrc === images[i].img) { - imageModalPointer = i; - break; - } - } - this.openModalWindow = true; - this.images = images; - this.imagePointer = imageModalPointer; - }; - AppComponent.prototype.cancelImageModel = function () { - this.openModalWindow = false; - }; - AppComponent = __decorate([ - core_1.Component({ - selector: 'my-app', - template: "\n

Example - Default

\n

you can directly access \"ImageModel\" directive for both listing thumbnails and popup images

\n\n \n

Example with thumbnail pointers

\n

you can list images in your file and then calling \"ImageModel\" directive to show images on popup only

\n
\n \n
\n
\n \n
\n\t" - }), - __metadata('design:paramtypes', []) - ], AppComponent); - return AppComponent; - }()); - exports_1("AppComponent", AppComponent); - } - } -}); -//# sourceMappingURL=app.component.js.map \ No newline at end of file diff --git a/app/app.component.js.map b/app/app.component.js.map deleted file mode 100644 index 67b52584..00000000 --- a/app/app.component.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"app.component.js","sourceRoot":"","sources":["app.component.ts"],"names":[],"mappings":"AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;YAuBH;gBAUE;oBATA,oBAAe,GAAS,KAAK,CAAC;oBAE9B,WAAM,GAAG;wBACP,EAAE,KAAK,EAAE,6CAA6C,EAAE,GAAG,EAAE,sCAAsC,EAAE,WAAW,EAAE,SAAS,EAAE;wBAC7H,EAAE,KAAK,EAAE,6CAA6C,EAAE,GAAG,EAAE,sCAAsC,EAAE,WAAW,EAAE,SAAS,EAAE;wBAC7H,EAAE,KAAK,EAAE,6CAA6C,EAAE,GAAG,EAAE,sCAAsC,EAAE,WAAW,EAAE,SAAS,EAAE;wBAC7H,EAAE,KAAK,EAAE,6CAA6C,EAAE,GAAG,EAAE,sCAAsC,EAAE,WAAW,EAAE,SAAS,EAAE;wBAC7H,EAAE,KAAK,EAAE,6CAA6C,EAAE,GAAG,EAAE,sCAAsC,EAAE,WAAW,EAAE,SAAS,EAAE;qBAC9H,CAAC;gBAGF,CAAC;gBACF,qCAAc,GAAd,UAAe,QAAQ,EAAC,MAAM;oBAC5B,IAAI,iBAAiB,CAAC;oBACtB,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBAClC,EAAE,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;4BAC/B,iBAAiB,GAAG,CAAC,CAAC;4BACtB,KAAK,CAAC;wBACR,CAAC;oBACN,CAAC;oBACH,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;oBAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;oBACrB,IAAI,CAAC,YAAY,GAAI,iBAAiB,CAAC;gBACzC,CAAC;gBACD,uCAAgB,GAAhB;oBACE,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;gBAC/B,CAAC;gBA/CF;oBAAC,gBAAS,CAAC;wBACP,QAAQ,EAAG,QAAQ;wBACnB,QAAQ,EAAG,86BAgBb;qBACD,CAAC;;gCAAA;gBA6BF,mBAAC;YAAD,CAAC,AA5BD,IA4BC;YA5BD,uCA4BC,CAAA"} \ No newline at end of file diff --git a/app/app.component.ts b/app/app.component.ts deleted file mode 100644 index 770262de..00000000 --- a/app/app.component.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * @author Vimala A - */ - -import {Component} from '@angular/core'; -@Component({ - selector : 'my-app', - template: ` -

Example - Default

-

you can directly access "ImageModel" directive for both listing thumbnails and popup images

- - -

Example with thumbnail pointers

-

you can list images in your file and then calling "ImageModel" directive to show images on popup only

-
- -
-
- -
- ` -}) -export class AppComponent { - openModalWindow:boolean=false; - imagePointer:number; - images = [ - { thumb: './app/assets/images/gallery/thumbs/img1.jpg', img: './app/assets/images/gallery/img1.jpg', description: 'Image 1' }, - { thumb: './app/assets/images/gallery/thumbs/img2.jpg', img: './app/assets/images/gallery/img2.jpg', description: 'Image 2' }, - { thumb: './app/assets/images/gallery/thumbs/img3.jpg', img: './app/assets/images/gallery/img3.jpg', description: 'Image 3' }, - { thumb: './app/assets/images/gallery/thumbs/img4.jpg', img: './app/assets/images/gallery/img4.jpg', description: 'Image 4' }, - { thumb: './app/assets/images/gallery/thumbs/img5.jpg', img: './app/assets/images/gallery/img5.jpg', description: 'Image 5' } - ]; - constructor() { - - } - OpenImageModel(imageSrc,images) { - var imageModalPointer; - for (var i = 0; i < images.length; i++) { - if (imageSrc === images[i].img) { - imageModalPointer = i; - break; - } - } - this.openModalWindow = true; - this.images = images; - this.imagePointer = imageModalPointer; - } - cancelImageModel() { - this.openModalWindow = false; - } -} diff --git a/app/app.module.js b/app/app.module.js deleted file mode 100644 index 513b15d5..00000000 --- a/app/app.module.js +++ /dev/null @@ -1,47 +0,0 @@ -System.register(['@angular/core', '@angular/platform-browser', './app.component', '../directives/angular2-image-popup/image-modal-popup'], function(exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; - }; - var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); - }; - var core_1, platform_browser_1, app_component_1, image_modal_popup_1; - var AppModule; - return { - setters:[ - function (core_1_1) { - core_1 = core_1_1; - }, - function (platform_browser_1_1) { - platform_browser_1 = platform_browser_1_1; - }, - function (app_component_1_1) { - app_component_1 = app_component_1_1; - }, - function (image_modal_popup_1_1) { - image_modal_popup_1 = image_modal_popup_1_1; - }], - execute: function() { - AppModule = (function () { - function AppModule() { - } - AppModule = __decorate([ - core_1.NgModule({ - declarations: [app_component_1.AppComponent, image_modal_popup_1.ImageModal], - imports: [platform_browser_1.BrowserModule], - bootstrap: [app_component_1.AppComponent], - }), - __metadata('design:paramtypes', []) - ], AppModule); - return AppModule; - }()); - exports_1("AppModule", AppModule); - } - } -}); -//# sourceMappingURL=app.module.js.map \ No newline at end of file diff --git a/app/app.module.js.map b/app/app.module.js.map deleted file mode 100644 index f62afefc..00000000 --- a/app/app.module.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"app.module.js","sourceRoot":"","sources":["app.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAUA;gBAAA;gBAAwB,CAAC;gBALzB;oBAAC,eAAQ,CAAC;wBACN,YAAY,EAAE,CAAC,4BAAY,EAAC,8BAAU,CAAC;wBACvC,OAAO,EAAO,CAAC,gCAAa,CAAC;wBAC7B,SAAS,EAAK,CAAC,4BAAY,CAAC;qBAC/B,CAAC;;6BAAA;gBACsB,gBAAC;YAAD,CAAC,AAAzB,IAAyB;YAAzB,iCAAyB,CAAA"} \ No newline at end of file diff --git a/app/app.module.ts b/app/app.module.ts deleted file mode 100644 index 99c9f94e..00000000 --- a/app/app.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; -import { AppComponent } from './app.component'; -import {ImageModal} from '../directives/angular2-image-popup/image-modal-popup'; - -@NgModule({ - declarations: [AppComponent,ImageModal], - imports: [BrowserModule], - bootstrap: [AppComponent], -}) -export class AppModule {} diff --git a/app/assets/css/main.css b/app/assets/css/main.css deleted file mode 100644 index 9b6ee706..00000000 --- a/app/assets/css/main.css +++ /dev/null @@ -1,27 +0,0 @@ -.more { - position: absolute; - /* margin: 0px; */ - /* top: 0px; */ - margin-top: 2px; - /* word-break: break-word; */ - background: rgba(0,0,0,0.7); - height: 50px; - width: 50px; - padding-left: 0px; - padding-top: 2px; - padding-top: 2px; - text-align: center; -} -.list-img { - margin-top: 2px; - cursor: pointer; -} -.float-left { - float: left; - margin-right:5px; - color:#ffffff; -} -.float-left a:hover { - color:red; - cursor: pointer; -} \ No newline at end of file diff --git a/app/assets/images/gallery/img1.jpg b/app/assets/images/gallery/img1.jpg deleted file mode 100644 index c35c10e3..00000000 Binary files a/app/assets/images/gallery/img1.jpg and /dev/null differ diff --git a/app/assets/images/gallery/img2.jpg b/app/assets/images/gallery/img2.jpg deleted file mode 100644 index 19b259da..00000000 Binary files a/app/assets/images/gallery/img2.jpg and /dev/null differ diff --git a/app/assets/images/gallery/img3.jpg b/app/assets/images/gallery/img3.jpg deleted file mode 100644 index 5292a92d..00000000 Binary files a/app/assets/images/gallery/img3.jpg and /dev/null differ diff --git a/app/assets/images/gallery/img4.jpg b/app/assets/images/gallery/img4.jpg deleted file mode 100644 index 8de928b1..00000000 Binary files a/app/assets/images/gallery/img4.jpg and /dev/null differ diff --git a/app/assets/images/gallery/img5.jpg b/app/assets/images/gallery/img5.jpg deleted file mode 100644 index 5994a393..00000000 Binary files a/app/assets/images/gallery/img5.jpg and /dev/null differ diff --git a/app/assets/images/gallery/thumbs/img1.jpg b/app/assets/images/gallery/thumbs/img1.jpg deleted file mode 100644 index 93986c47..00000000 Binary files a/app/assets/images/gallery/thumbs/img1.jpg and /dev/null differ diff --git a/app/assets/images/gallery/thumbs/img2.jpg b/app/assets/images/gallery/thumbs/img2.jpg deleted file mode 100644 index 0ef664d1..00000000 Binary files a/app/assets/images/gallery/thumbs/img2.jpg and /dev/null differ diff --git a/app/assets/images/gallery/thumbs/img3.jpg b/app/assets/images/gallery/thumbs/img3.jpg deleted file mode 100644 index ad326e1b..00000000 Binary files a/app/assets/images/gallery/thumbs/img3.jpg and /dev/null differ diff --git a/app/assets/images/gallery/thumbs/img4.jpg b/app/assets/images/gallery/thumbs/img4.jpg deleted file mode 100644 index 19cdc074..00000000 Binary files a/app/assets/images/gallery/thumbs/img4.jpg and /dev/null differ diff --git a/app/assets/images/gallery/thumbs/img5.jpg b/app/assets/images/gallery/thumbs/img5.jpg deleted file mode 100644 index 01310081..00000000 Binary files a/app/assets/images/gallery/thumbs/img5.jpg and /dev/null differ diff --git a/app/main.js b/app/main.js deleted file mode 100644 index 19eaa541..00000000 --- a/app/main.js +++ /dev/null @@ -1,20 +0,0 @@ -// import {bootstrap} from '@angular/platform-browser-dynamic'; -// import {AppComponent} from './app.component'; -System.register(['@angular/platform-browser-dynamic', './app.module'], function(exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var platform_browser_dynamic_1, app_module_1; - return { - setters:[ - function (platform_browser_dynamic_1_1) { - platform_browser_dynamic_1 = platform_browser_dynamic_1_1; - }, - function (app_module_1_1) { - app_module_1 = app_module_1_1; - }], - execute: function() { - platform_browser_dynamic_1.platformBrowserDynamic().bootstrapModule(app_module_1.AppModule); - } - } -}); -//# sourceMappingURL=main.js.map \ No newline at end of file diff --git a/app/main.js.map b/app/main.js.map deleted file mode 100644 index fb17e6f2..00000000 --- a/app/main.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"main.js","sourceRoot":"","sources":["main.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,gDAAgD;;;;;;;;;;;;;;YAMhD,iDAAsB,EAAE,CAAC,eAAe,CAAC,sBAAS,CAAC,CAAC"} \ No newline at end of file diff --git a/app/main.ts b/app/main.ts deleted file mode 100644 index a4fe6fd5..00000000 --- a/app/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -// import {bootstrap} from '@angular/platform-browser-dynamic'; -// import {AppComponent} from './app.component'; - -// bootstrap(AppComponent); -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { AppModule } from './app.module'; - -platformBrowserDynamic().bootstrapModule(AppModule); \ No newline at end of file diff --git a/bower.json b/bower.json deleted file mode 100644 index 0fff4b72..00000000 --- a/bower.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "angular2-image-popup", - "authors": [ - "Vimala A (vimalamca1991@gmcail.com)" - ], - "description": "Image popup directive for angular2", - "main": "", - "moduleType": [ - "es6", - "node" - ], - "keywords": [ - "angular2", - "angular2-image-popup", - "angular2-image", - "image-popup", - "popup", - "modal", - "angular2-modal-popup", - "modal-popup" - ], - "license": "MIT", - "homepage": "", - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests" - ] -} diff --git a/directives/angular2-image-popup/angular2-image-popup.js b/directives/angular2-image-popup/angular2-image-popup.js deleted file mode 100644 index d7b740d0..00000000 --- a/directives/angular2-image-popup/angular2-image-popup.js +++ /dev/null @@ -1,99 +0,0 @@ -System.register(['@angular/core'], function(exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; - }; - var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); - }; - var core_1; - var ImageModal; - return { - setters:[ - function (core_1_1) { - core_1 = core_1_1; - }], - execute: function() { - ImageModal = (function () { - function ImageModal(element) { - this.element = element; - this.opened = false; - this.loading = false; - this.showRepeat = false; - this.cancelEvent = new core_1.EventEmitter(); - this._element = this.element.nativeElement; - } - ImageModal.prototype.ngOnInit = function () { - this.loading = true; - if (this.imagePointer >= 0) { - this.showRepeat = false; - this.openGallery(this.imagePointer); - } - else { - this.showRepeat = true; - } - }; - ImageModal.prototype.closeGallery = function () { - this.opened = false; - this.cancelEvent.emit(null); - }; - ImageModal.prototype.prevImage = function () { - this.loading = true; - this.currentImageIndex--; - if (this.currentImageIndex < 0) { - this.currentImageIndex = this.modalImages.length - 1; - } - this.openGallery(this.currentImageIndex); - }; - ImageModal.prototype.nextImage = function () { - this.loading = true; - this.currentImageIndex++; - if (this.modalImages.length === this.currentImageIndex) { - this.currentImageIndex = 0; - } - this.openGallery(this.currentImageIndex); - }; - ImageModal.prototype.openGallery = function (index) { - if (!index) { - this.currentImageIndex = 1; - } - this.currentImageIndex = index; - this.opened = true; - for (var i = 0; i < this.modalImages.length; i++) { - if (i === this.currentImageIndex) { - this.imgSrc = this.modalImages[i].img; - this.loading = false; - break; - } - } - }; - __decorate([ - core_1.Input('modalImages'), - __metadata('design:type', Object) - ], ImageModal.prototype, "modalImages", void 0); - __decorate([ - core_1.Input('imagePointer'), - __metadata('design:type', Number) - ], ImageModal.prototype, "imagePointer", void 0); - __decorate([ - core_1.Output('cancelEvent'), - __metadata('design:type', Object) - ], ImageModal.prototype, "cancelEvent", void 0); - ImageModal = __decorate([ - core_1.Component({ - selector: 'ImageModal', - template: "\n
\n
\n \"Image\n
\n
\n
\n \n
\n " - }), - __metadata('design:paramtypes', [core_1.ElementRef]) - ], ImageModal); - return ImageModal; - }()); - exports_1("ImageModal", ImageModal); - } - } -}); -//# sourceMappingURL=angular2-image-popup.js.map \ No newline at end of file diff --git a/directives/angular2-image-popup/angular2-image-popup.js.map b/directives/angular2-image-popup/angular2-image-popup.js.map deleted file mode 100644 index 44050e4c..00000000 --- a/directives/angular2-image-popup/angular2-image-popup.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"angular2-image-popup.js","sourceRoot":"","sources":["angular2-image-popup.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;YAsBA;gBAUE,oBAAmB,OAAmB;oBAAnB,YAAO,GAAP,OAAO,CAAY;oBAR9B,WAAM,GAAW,KAAK,CAAC;oBAGvB,YAAO,GAAU,KAAK,CAAC;oBACvB,eAAU,GAAU,KAAK,CAAC;oBAGX,gBAAW,GAAG,IAAI,mBAAY,EAAO,CAAC;oBAE3D,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC7C,CAAC;gBACD,6BAAQ,GAAR;oBACI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;oBACpB,EAAE,CAAA,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC,CAAC;wBAC5B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;wBACxB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;oBACtC,CAAC;oBAAC,IAAI,CAAC,CAAC;wBACN,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;oBACzB,CAAC;gBACH,CAAC;gBACD,iCAAY,GAAZ;oBACE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;oBACpB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC9B,CAAC;gBACD,8BAAS,GAAT;oBACE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;oBACpB,IAAI,CAAC,iBAAiB,EAAE,CAAC;oBACzB,EAAE,CAAA,CAAC,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC;wBAC9B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,GAAC,CAAC,CAAG;oBACvD,CAAC;oBACD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;gBAC3C,CAAC;gBACD,8BAAS,GAAT;oBACE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;oBACpB,IAAI,CAAC,iBAAiB,EAAE,CAAC;oBACzB,EAAE,CAAA,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;wBACtD,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;oBAC7B,CAAC;oBACD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;gBAE3C,CAAC;gBACD,gCAAW,GAAX,UAAY,KAAK;oBACf,EAAE,CAAA,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;wBACZ,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;oBAC3B,CAAC;oBACD,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;oBAC7B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;oBACpB,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBAC5C,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,iBAAkB,CAAC,CAAC,CAAC;4BAClC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;4BACtC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;4BACrB,KAAK,CAAC;wBACR,CAAC;oBACN,CAAC;gBACN,CAAC;gBAjDD;oBAAC,YAAK,CAAC,aAAa,CAAC;;+DAAA;gBACrB;oBAAC,YAAK,CAAC,cAAc,CAAC;;gEAAA;gBACtB;oBAAC,aAAM,CAAC,aAAa,CAAC;;+DAAA;gBA7BxB;oBAAC,gBAAS,CAAC;wBACP,QAAQ,EAAE,YAAY;wBACvB,QAAQ,EAAE,w/BAgBL;qBACP,CAAC;;8BAAA;gBA0DF,iBAAC;YAAD,CAAC,AAzDD,IAyDC;YAzDD,mCAyDC,CAAA"} \ No newline at end of file diff --git a/directives/angular2-image-popup/angular2-image-popup.ts b/directives/angular2-image-popup/angular2-image-popup.ts deleted file mode 100644 index f5e64f1d..00000000 --- a/directives/angular2-image-popup/angular2-image-popup.ts +++ /dev/null @@ -1,80 +0,0 @@ -import {Component, Input,Output,ElementRef,EventEmitter,OnInit} from '@angular/core'; - -@Component({ - selector: 'ImageModal', - template: ` - -
- -
- ` -}) -export class ImageModal implements OnInit { - public _element:any; - public opened:boolean = false; - public imgSrc:string; - public currentImageIndex:number; - public loading:boolean= false; - public showRepeat:boolean= false; - @Input('modalImages') public modalImages:any; - @Input('imagePointer') public imagePointer:number; - @Output('cancelEvent') cancelEvent = new EventEmitter(); - constructor(public element: ElementRef) { - this._element = this.element.nativeElement; - } - ngOnInit() { - this.loading = true; - if(this.imagePointer >= 0) { - this.showRepeat = false; - this.openGallery(this.imagePointer); - } else { - this.showRepeat = true; - } - } - closeGallery() { - this.opened = false; - this.cancelEvent.emit(null); - } - prevImage() { - this.loading = true; - this.currentImageIndex--; - if(this.currentImageIndex < 0) { - this.currentImageIndex = this.modalImages.length-1 ; - } - this.openGallery(this.currentImageIndex); - } - nextImage() { - this.loading = true; - this.currentImageIndex++; - if(this.modalImages.length === this.currentImageIndex) { - this.currentImageIndex = 0; - } - this.openGallery(this.currentImageIndex); - - } - openGallery(index) { - if(!index) { - this.currentImageIndex = 1; - } - this.currentImageIndex = index; - this.opened = true; - for (var i = 0; i < this.modalImages.length; i++) { - if (i === this.currentImageIndex ) { - this.imgSrc = this.modalImages[i].img; - this.loading = false; - break; - } - } - } -} diff --git a/directives/angular2-image-popup/css/style.css b/directives/angular2-image-popup/css/style.css deleted file mode 100644 index 0b2b4ff6..00000000 --- a/directives/angular2-image-popup/css/style.css +++ /dev/null @@ -1,266 +0,0 @@ -.ng-gallery { - width: 100%; - display: inline-block; -} - -img.ng-thumb { - height: 50px; - float: left; - display: block; - cursor: pointer; - margin: 2px 2px 0 0; -} - -.ng-overlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(0,0,0,0.8); - /*opacity: 0.85;*/ - z-index: 9999; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-user-drag: none; -} - -.ng-gallery-content { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 10000; - text-align: center; -} - -.ng-gallery-content > a.close-popup { - font-size: 42px; - float: right; - color: #fff; - text-decoration: none; - margin: 0 30px 0 0; - cursor: pointer; - position: absolute; - top: 20px; - right: 0; -} - -.ng-gallery-content > a.download-image { - font-size: 42px; - float: right; - color: #fff; - text-decoration: none; - margin: 0 30px 0 0; - cursor: pointer; - position: absolute; - top: 20px; - right: 63px; -} - -.ng-gallery-content > a.nav-left, .ng-gallery-content > a.nav-right { - color: #fff; - text-decoration: none; - font-size: 60px; - cursor: pointer; - outline: none; -} - -.ng-gallery-content > a.nav-left { - position: fixed; - left: 30px; - top: 50%; - transform: translateY(-50%); -} - -.ng-gallery-content > a.nav-right { - position: fixed; - right: 30px; - top: 50%; - transform: translateY(-50%); -} - -.ng-gallery-content > img { - height: auto; - max-height: calc(100% - 150px); - max-width: calc(100% - 100px); - position: relative; - display: block; - margin: 0 auto 0 auto; - top: 50%; - transform: translateY(-50%); - -webkit-transform: translateY(-50%); - cursor: pointer; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-user-drag: none; -} - -.ng-gallery-content > img.effect { - animation: fadeIn 0.5s; -} - -@keyframes fadeIn { - from { opacity: 0.3; } - to { opacity: 1; } -} - -.ng-gallery-content > span.info-text { - color: #fff; - display: inline-block; - width: 100%; - height: 20px; - font-weight: bold; - text-align: center; - position: fixed; - left: 0; - right: 0; - bottom: 100px; -} - -.ng-gallery-content > .ng-thumbnails-wrapper { - width: 400px; - height: 70px; - text-align: center; - position: fixed; - bottom: 20px; - left: 0; - right: 0; - margin-left: auto; - margin-right: auto; - overflow-x: hidden; -} - -.ng-gallery-content > .ng-thumbnails-wrapper > .ng-thumbnails { - width: 4000px; - height: 70px; -} - -.ng-gallery-content > .ng-thumbnails-wrapper > .ng-thumbnails > div > img { - width: auto; - height: 70px; - float: left; - margin-right: 10px; - cursor: pointer; - opacity: 0.6; -} - -.ng-gallery-content > .ng-thumbnails-wrapper > .ng-thumbnails > div > img:hover, -.ng-gallery-content > .ng-thumbnails-wrapper > .ng-thumbnails > div > img.active { - transition: opacity 0.25s ease; - opacity: 1; -} - -/* Loading - from http://loading.io */ -uiload { - display: inline-block; - position: relative; -} - -uiload > div { - position: relative; -} - -@-webkit-keyframes uil-ring-anim { - 0% { - -ms-transform: rotate(0deg); - -moz-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - -o-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -ms-transform: rotate(360deg); - -moz-transform: rotate(360deg); - -webkit-transform: rotate(360deg); - -o-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -@-moz-keyframes uil-ring-anim { - 0% { - -ms-transform: rotate(0deg); - -moz-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - -o-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -ms-transform: rotate(360deg); - -moz-transform: rotate(360deg); - -webkit-transform: rotate(360deg); - -o-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -@-ms-keyframes uil-ring-anim { - 0% { - -ms-transform: rotate(0deg); - -moz-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - -o-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -ms-transform: rotate(360deg); - -moz-transform: rotate(360deg); - -webkit-transform: rotate(360deg); - -o-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -@keyframes uil-ring-anim { - 0% { - -ms-transform: rotate(0deg); - -moz-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - -o-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -ms-transform: rotate(360deg); - -moz-transform: rotate(360deg); - -webkit-transform: rotate(360deg); - -o-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -.uil-ring-css { - background: none; - position: relative; - top: 0; - margin: 180px auto 0 auto; - width: 100px; - height: 100px; -} - -.uil-ring-css > div { - position: absolute; - display: block; - width: 80px; - height: 80px; - top: 20px; - left: 20px; - border-radius: 40px; - box-shadow: 0 6px 0 0 #fff; - -ms-animation: uil-ring-anim 1s linear infinite; - -moz-animation: uil-ring-anim 1s linear infinite; - -webkit-animation: uil-ring-anim 1s linear infinite; - -o-animation: uil-ring-anim 1s linear infinite; - animation: uil-ring-anim 1s linear infinite; -} \ No newline at end of file diff --git a/directives/angular2-image-popup/image-modal-popup.js b/directives/angular2-image-popup/image-modal-popup.js deleted file mode 100644 index 0e2ef996..00000000 --- a/directives/angular2-image-popup/image-modal-popup.js +++ /dev/null @@ -1,25 +0,0 @@ -System.register(['./angular2-image-popup'], function(exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var angular2_image_popup_1; - function exportStar_1(m) { - var exports = {}; - for(var n in m) { - if (n !== "default") exports[n] = m[n]; - } - exports_1(exports); - } - return { - setters:[ - function (angular2_image_popup_1_1) { - angular2_image_popup_1 = angular2_image_popup_1_1; - exportStar_1(angular2_image_popup_1_1); - }], - execute: function() { - exports_1("default",{ - directives: [angular2_image_popup_1.ImageModal] - }); - } - } -}); -//# sourceMappingURL=image-modal-popup.js.map \ No newline at end of file diff --git a/directives/angular2-image-popup/image-modal-popup.js.map b/directives/angular2-image-popup/image-modal-popup.js.map deleted file mode 100644 index 49236eb9..00000000 --- a/directives/angular2-image-popup/image-modal-popup.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"image-modal-popup.js","sourceRoot":"","sources":["image-modal-popup.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;YAIA,oBAAe;gBACX,UAAU,EAAE,CAAC,iCAAU,CAAC;aAC3B,EAAA"} \ No newline at end of file diff --git a/directives/angular2-image-popup/image-modal-popup.ts b/directives/angular2-image-popup/image-modal-popup.ts deleted file mode 100644 index 727c43db..00000000 --- a/directives/angular2-image-popup/image-modal-popup.ts +++ /dev/null @@ -1,7 +0,0 @@ -import {ImageModal} from './angular2-image-popup'; - -export * from './angular2-image-popup'; - -export default { - directives: [ImageModal] -} diff --git a/examples/angular-cli-19/.editorconfig b/examples/angular-cli-19/.editorconfig new file mode 100644 index 00000000..59d9a3a3 --- /dev/null +++ b/examples/angular-cli-19/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/examples/angular-cli-19/.gitignore b/examples/angular-cli-19/.gitignore new file mode 100644 index 00000000..0711527e --- /dev/null +++ b/examples/angular-cli-19/.gitignore @@ -0,0 +1,42 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings + +# System files +.DS_Store +Thumbs.db diff --git a/examples/angular-cli-19/.vscode/extensions.json b/examples/angular-cli-19/.vscode/extensions.json new file mode 100644 index 00000000..77b37457 --- /dev/null +++ b/examples/angular-cli-19/.vscode/extensions.json @@ -0,0 +1,4 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 + "recommendations": ["angular.ng-template"] +} diff --git a/examples/angular-cli-19/.vscode/launch.json b/examples/angular-cli-19/.vscode/launch.json new file mode 100644 index 00000000..925af837 --- /dev/null +++ b/examples/angular-cli-19/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "ng serve", + "type": "chrome", + "request": "launch", + "preLaunchTask": "npm: start", + "url": "http://localhost:4200/" + }, + { + "name": "ng test", + "type": "chrome", + "request": "launch", + "preLaunchTask": "npm: test", + "url": "http://localhost:9876/debug.html" + } + ] +} diff --git a/examples/angular-cli-19/.vscode/tasks.json b/examples/angular-cli-19/.vscode/tasks.json new file mode 100644 index 00000000..a298b5bd --- /dev/null +++ b/examples/angular-cli-19/.vscode/tasks.json @@ -0,0 +1,42 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "start", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "(.*?)" + }, + "endsPattern": { + "regexp": "bundle generation complete" + } + } + } + }, + { + "type": "npm", + "script": "test", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "(.*?)" + }, + "endsPattern": { + "regexp": "bundle generation complete" + } + } + } + } + ] +} diff --git a/examples/angular-cli-19/angular.json b/examples/angular-cli-19/angular.json new file mode 100644 index 00000000..9ec52035 --- /dev/null +++ b/examples/angular-cli-19/angular.json @@ -0,0 +1,106 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "angular-cli": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:application", + "options": { + "outputPath": "dist/angular-cli", + "index": "src/index.html", + "browser": "src/main.ts", + "polyfills": [ + "zone.js" + ], + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "src/favicon.png", + "src/assets", + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "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": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-cli:build:production" + }, + "development": { + "buildTarget": "angular-cli:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n" + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "polyfills": [ + "zone.js", + "zone.js/testing" + ], + "tsConfig": "tsconfig.spec.json", + "inlineStyleLanguage": "scss", + "assets": [ + "src/favicon.png", + "src/assets", + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [] + } + } + } + } + } +} diff --git a/examples/angular-cli-19/package-lock.json b/examples/angular-cli-19/package-lock.json new file mode 100644 index 00000000..034f3e69 --- /dev/null +++ b/examples/angular-cli-19/package-lock.json @@ -0,0 +1,13718 @@ +{ + "name": "angular-cli", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "angular-cli", + "version": "0.0.0", + "dependencies": { + "@angular/animations": "^19.0.5", + "@angular/cdk": "^19.0.4", + "@angular/common": "^19.0.5", + "@angular/compiler": "^19.0.5", + "@angular/core": "^19.0.5", + "@angular/forms": "^19.0.5", + "@angular/platform-browser": "^19.0.5", + "@angular/platform-browser-dynamic": "^19.0.5", + "@angular/router": "^19.0.5", + "@fortawesome/fontawesome-svg-core": "^6.7.2", + "@fortawesome/free-solid-svg-icons": "^6.7.2", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^19.0.6", + "@angular/cli": "~19.0.6", + "@angular/compiler-cli": "^19.0.5", + "@types/jasmine": "~5.1.0", + "@types/node": "^20.10.0", + "jasmine-core": "~5.1.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.6.3" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@angular-devkit/architect": { + "version": "0.1900.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1900.6.tgz", + "integrity": "sha512-w11bAXQnNWBawTJfQPjvaTRrzrqsOUm9tK9WNvaia/xjiRFpmO0CfmKtn3axNSEJM8jb/czaNQrgTwG+TGc/8g==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "19.0.6", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/architect/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/architect/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/architect/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/architect/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/build-angular": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-19.0.6.tgz", + "integrity": "sha512-dWTAsE6BSI8z0xglQdYBdqTBwg1Q+RWE3OrmlGs+520Dcoq/F0Z41Y1F3MiuHuQPdDAIQr88iB0APkIRW4clMg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1900.6", + "@angular-devkit/build-webpack": "0.1900.6", + "@angular-devkit/core": "19.0.6", + "@angular/build": "19.0.6", + "@babel/core": "7.26.0", + "@babel/generator": "7.26.2", + "@babel/helper-annotate-as-pure": "7.25.9", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-transform-async-generator-functions": "7.25.9", + "@babel/plugin-transform-async-to-generator": "7.25.9", + "@babel/plugin-transform-runtime": "7.25.9", + "@babel/preset-env": "7.26.0", + "@babel/runtime": "7.26.0", + "@discoveryjs/json-ext": "0.6.3", + "@ngtools/webpack": "19.0.6", + "@vitejs/plugin-basic-ssl": "1.1.0", + "ansi-colors": "4.1.3", + "autoprefixer": "10.4.20", + "babel-loader": "9.2.1", + "browserslist": "^4.21.5", + "copy-webpack-plugin": "12.0.2", + "css-loader": "7.1.2", + "esbuild-wasm": "0.24.0", + "fast-glob": "3.3.2", + "http-proxy-middleware": "3.0.3", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", + "karma-source-map-support": "1.4.0", + "less": "4.2.0", + "less-loader": "12.2.0", + "license-webpack-plugin": "4.0.2", + "loader-utils": "3.3.1", + "mini-css-extract-plugin": "2.9.2", + "open": "10.1.0", + "ora": "5.4.1", + "picomatch": "4.0.2", + "piscina": "4.7.0", + "postcss": "8.4.49", + "postcss-loader": "8.1.1", + "resolve-url-loader": "5.0.0", + "rxjs": "7.8.1", + "sass": "1.80.7", + "sass-loader": "16.0.3", + "semver": "7.6.3", + "source-map-loader": "5.0.0", + "source-map-support": "0.5.21", + "terser": "5.36.0", + "tree-kill": "1.2.2", + "tslib": "2.8.1", + "webpack": "5.96.1", + "webpack-dev-middleware": "7.4.2", + "webpack-dev-server": "5.1.0", + "webpack-merge": "6.0.1", + "webpack-subresource-integrity": "5.1.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "esbuild": "0.24.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^19.0.0", + "@angular/localize": "^19.0.0", + "@angular/platform-server": "^19.0.0", + "@angular/service-worker": "^19.0.0", + "@angular/ssr": "^19.0.6", + "@web/test-runner": "^0.19.0", + "browser-sync": "^3.0.2", + "jest": "^29.5.0", + "jest-environment-jsdom": "^29.5.0", + "karma": "^6.3.0", + "ng-packagr": "^19.0.0", + "protractor": "^7.0.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=5.5 <5.7" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "@web/test-runner": { + "optional": true + }, + "browser-sync": { + "optional": true + }, + "jest": { + "optional": true + }, + "jest-environment-jsdom": { + "optional": true + }, + "karma": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "protractor": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.1900.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1900.6.tgz", + "integrity": "sha512-WehtVrbBow4fc7hsaUKb+BZ6MDE5lO98/tgv7GR5PkRdGKnyLA0pW1AfPLJJQDgcaKjneramMhDFNc1eGSX0mQ==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1900.6", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "webpack": "^5.30.0", + "webpack-dev-server": "^5.0.2" + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.0.6.tgz", + "integrity": "sha512-R9hlHfAh1HKoIWgnYJlOEKhUezhTNl0fpUmHxG2252JSY5FLRxmYArTtJYYmbNdBbsBLNg3UHyM/GBPvJSA3NQ==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "19.0.6", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.12", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/animations": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-19.0.5.tgz", + "integrity": "sha512-HCOF2CrhUvjoZWusd4nh32VOxpUrg6bV+3Z8Q36Ix3aZdni8v0qoP2rl5wGbotaPtYg5RtyDH60Z2AOPKqlrZg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.0.5" + } + }, + "node_modules/@angular/build": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-19.0.6.tgz", + "integrity": "sha512-KEVNLgTZUF2dfpOYQn+yR2HONHUTxq/2rFVhiK9qAvrm/m+uKJNEXx7hGtbRyoqenZff4ScJq+7feITUldfX8g==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1900.6", + "@babel/core": "7.26.0", + "@babel/helper-annotate-as-pure": "7.25.9", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-syntax-import-attributes": "7.26.0", + "@inquirer/confirm": "5.0.2", + "@vitejs/plugin-basic-ssl": "1.1.0", + "beasties": "0.1.0", + "browserslist": "^4.23.0", + "esbuild": "0.24.0", + "fast-glob": "3.3.2", + "https-proxy-agent": "7.0.5", + "istanbul-lib-instrument": "6.0.3", + "listr2": "8.2.5", + "magic-string": "0.30.12", + "mrmime": "2.0.0", + "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "4.0.2", + "piscina": "4.7.0", + "rollup": "4.26.0", + "sass": "1.80.7", + "semver": "7.6.3", + "vite": "5.4.11", + "watchpack": "2.4.2" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "lmdb": "3.1.5" + }, + "peerDependencies": { + "@angular/compiler": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "@angular/localize": "^19.0.0", + "@angular/platform-server": "^19.0.0", + "@angular/service-worker": "^19.0.0", + "@angular/ssr": "^19.0.6", + "less": "^4.2.0", + "postcss": "^8.4.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=5.5 <5.7" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "less": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular/build/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular/build/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular/cdk": { + "version": "19.0.4", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-19.0.4.tgz", + "integrity": "sha512-P8V1n6AFFjBUJG3YRgw8DiiNDWPZVrwQ42wbwgZxd4s2TQAuNFg3YY8h/DSMVxt2sXpavrshZsoLtP9yLKZjHA==", + "dependencies": { + "tslib": "^2.3.0" + }, + "optionalDependencies": { + "parse5": "^7.1.2" + }, + "peerDependencies": { + "@angular/common": "^19.0.0 || ^20.0.0", + "@angular/core": "^19.0.0 || ^20.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/cli": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-19.0.6.tgz", + "integrity": "sha512-ZEHhgRRVIdn10dbsAjB8TE9Co32hfuL9/im5Jcfa1yrn6KJefmigz6KN8Xu7FXMH5FkdqfQ11QpLBxJSPb9aww==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1900.6", + "@angular-devkit/core": "19.0.6", + "@angular-devkit/schematics": "19.0.6", + "@inquirer/prompts": "7.1.0", + "@listr2/prompt-adapter-inquirer": "2.0.18", + "@schematics/angular": "19.0.6", + "@yarnpkg/lockfile": "1.1.0", + "ini": "5.0.0", + "jsonc-parser": "3.3.1", + "listr2": "8.2.5", + "npm-package-arg": "12.0.0", + "npm-pick-manifest": "10.0.0", + "pacote": "20.0.0", + "resolve": "1.22.8", + "semver": "7.6.3", + "symbol-observable": "4.0.0", + "yargs": "17.7.2" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/cli/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular/cli/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular/cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/cli/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/cli/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular/common": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-19.0.5.tgz", + "integrity": "sha512-fFK+euCj1AjBHBCpj9VnduMSeqoMRhZZHbhPYiND7tucRRJ8vwGU0sYK2KI/Ko+fsrNIXL/0O4F36jVPl09Smg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.0.5", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/compiler": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-19.0.5.tgz", + "integrity": "sha512-S8ku5Ljp0kqX3shfmE9DVo09629jeYJSlBRGbj2Glb92dd+VQZPOz7KxqKRTwmAl7lQIV/+4Lr6G/GVTsoC4vg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.0.5" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + } + } + }, + "node_modules/@angular/compiler-cli": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.0.5.tgz", + "integrity": "sha512-KSzuWCTZlvJsoAenxM9cjTOzNM8mrFxDBInj0KVPz7QU83amGS4rcv1pWO/QGYQcErfskcN84TAdMegaRWWCmA==", + "dev": true, + "dependencies": { + "@babel/core": "7.26.0", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^4.0.0", + "convert-source-map": "^1.5.1", + "reflect-metadata": "^0.2.0", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^17.2.1" + }, + "bin": { + "ng-xi18n": "bundles/src/bin/ng_xi18n.js", + "ngc": "bundles/src/bin/ngc.js", + "ngcc": "bundles/ngcc/index.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/compiler": "19.0.5", + "typescript": ">=5.5 <5.7" + } + }, + "node_modules/@angular/compiler-cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/compiler-cli/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/core": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-19.0.5.tgz", + "integrity": "sha512-Ywc6sPO6G/Y1stfk3y/MallV/h0yzQ0vdOHRWueLrk5kD1DTdbolV4X03Cs3PuVvravgcSVE3nnuuHFuH32emQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.15.0" + } + }, + "node_modules/@angular/forms": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-19.0.5.tgz", + "integrity": "sha512-OhNFkfOoguqCDq07vNBV28FFrmTM8S11Z3Cd6PQZJJF9TgAtpV5KtF7A3eXBCN92W4pmqluomPjfK7YyImzIYQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.0.5", + "@angular/core": "19.0.5", + "@angular/platform-browser": "19.0.5", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.0.5.tgz", + "integrity": "sha512-41+Jo5DEil4Ifvv+UE/p1l9YJtYN+xfhx+/C9cahVgvV5D2q+givyK73d0Mnb6XOfe1q+hoV5lZ+XhQYp21//g==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/animations": "19.0.5", + "@angular/common": "19.0.5", + "@angular/core": "19.0.5" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/platform-browser-dynamic": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-19.0.5.tgz", + "integrity": "sha512-KKFdue/uJVxkWdrntRAXkz+ycp4nD3SuGOH5pPf2svCBxieuHuFlWDi+DYVuFSEpC/ICCmlhrtzIAm44A4qzzQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.0.5", + "@angular/compiler": "19.0.5", + "@angular/core": "19.0.5", + "@angular/platform-browser": "19.0.5" + } + }, + "node_modules/@angular/router": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-19.0.5.tgz", + "integrity": "sha512-6tNubVVj/rRyTg+OXjQxACfufvCLHAwDQtv9wqt6q/3OYSnysHTik3ho3FaFPwu7fXJ+6p9Rjzkh2VY9QMk4bw==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.0.5", + "@angular/core": "19.0.5", + "@angular/platform-browser": "19.0.5", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", + "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.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/convert-source-map": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "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==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.26.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz", + "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", + "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", + "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.38.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.26.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", + "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.3", + "@babel/parser": "^7.26.3", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.3", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", + "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.26.3", + "@babel/types": "^7.26.3", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", + "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", + "dev": true, + "engines": { + "node": ">=14.17.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", + "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz", + "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz", + "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz", + "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz", + "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz", + "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz", + "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz", + "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz", + "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz", + "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz", + "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz", + "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz", + "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz", + "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz", + "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz", + "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz", + "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz", + "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz", + "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz", + "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz", + "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz", + "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz", + "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz", + "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.2.tgz", + "integrity": "sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.2.tgz", + "integrity": "sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.2.tgz", + "integrity": "sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.0.4.tgz", + "integrity": "sha512-fYAKCAcGNMdfjL6hZTRUwkIByQ8EIZCXKrIQZH7XjADnN/xvRUhj8UdBbpC4zoUzvChhkSC/zRKaP/tDs3dZpg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.0.2.tgz", + "integrity": "sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/core": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.2.tgz", + "integrity": "sha512-bHd96F3ezHg1mf/J0Rb4CV8ndCN0v28kUlrHqP7+ECm1C/A+paB7Xh2lbMk6x+kweQC+rZOxM/YeKikzxco8bQ==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core/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==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.1.tgz", + "integrity": "sha512-xn9aDaiP6nFa432i68JCaL302FyL6y/6EG97nAtfIPnWZ+mWPgCMLGc4XZ2QQMsZtu9q3Jd5AzBPjXh10aX9kA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.4.tgz", + "integrity": "sha512-GYocr+BPyxKPxQ4UZyNMqZFSGKScSUc0Vk17II3J+0bDcgGsQm0KYQNooN1Q5iBfXsy3x/VWmHGh20QnzsaHwg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.9.tgz", + "integrity": "sha512-BXvGj0ehzrngHTPTDqUoDT3NXL8U0RxUk2zJm2A66RhCEIWdtU1v6GuUqNAgArW4PQ9CinqIWyHdQgdwOj06zQ==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.1.tgz", + "integrity": "sha512-nAXAHQndZcXB+7CyjIW3XuQZZHbQQ0q8LX6miY6bqAWwDzNa9JUioDBYrFmOUNIsuF08o1WT/m2gbBXvBhYVxg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.4.tgz", + "integrity": "sha512-DX7a6IXRPU0j8kr2ovf+QaaDiIf+zEKaZVzCWdLOTk7XigqSXvoh4cul7x68xp54WTQrgSnW7P1WBJDbyY3GhA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.4.tgz", + "integrity": "sha512-wiliQOWdjM8FnBmdIHtQV2Ca3S1+tMBUerhyjkRCv1g+4jSvEweGu9GCcvVEgKDhTBT15nrxvk5/bVrGUqSs1w==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.1.0.tgz", + "integrity": "sha512-5U/XiVRH2pp1X6gpNAjWOglMf38/Ys522ncEHIKT1voRUvSj/DQnR22OVxHnwu5S+rCFaUiPQ57JOtMFQayqYA==", + "dev": true, + "dependencies": { + "@inquirer/checkbox": "^4.0.2", + "@inquirer/confirm": "^5.0.2", + "@inquirer/editor": "^4.1.0", + "@inquirer/expand": "^4.0.2", + "@inquirer/input": "^4.0.2", + "@inquirer/number": "^3.0.2", + "@inquirer/password": "^4.0.2", + "@inquirer/rawlist": "^4.0.2", + "@inquirer/search": "^3.0.2", + "@inquirer/select": "^4.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.0.4.tgz", + "integrity": "sha512-IsVN2EZdNHsmFdKWx9HaXb8T/s3FlR/U1QPt9dwbSyPtjFbMTlW9CRFvnn0bm/QIsrMRD2oMZqrQpSWPQVbXXg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/search": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.4.tgz", + "integrity": "sha512-tSkJk2SDmC2MEdTIjknXWmCnmPr5owTs9/xjfa14ol1Oh95n6xW7SYn5fiPk4/vrJPys0ggSWiISdPze4LTa7A==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/select": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.0.4.tgz", + "integrity": "sha512-ZzYLuLoUzTIW9EJm++jBpRiTshGqS3Q1o5qOEQqgzaBlmdsjQr6pA4TUNkwu6OBYgM2mIRbCz6mUhFDfl/GF+w==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.2.tgz", + "integrity": "sha512-ZhQ4TvhwHZF+lGhQ2O/rsjo80XoZR5/5qhOY3t6FJuX5XBg5Be8YzYTvaUGJnc12AUGI2nr4QSUE4PhKSigx7g==", + "dev": true, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/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==", + "dev": true + }, + "node_modules/@isaacs/cliui/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==", + "dev": true, + "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/@isaacs/cliui/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/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==", + "dev": true, + "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/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "dev": true, + "license": "MIT", + "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.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.1.tgz", + "integrity": "sha512-osjeBqMJ2lb/j/M8NCPjs1ylqWIcTRTycIhVB5pt6LgzgeRSb0YRZ7j9RfA8wIUrsr/medIuhVyonXRZWLyfdw==", + "dev": true, + "dependencies": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.5.0.tgz", + "integrity": "sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true + }, + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.18.tgz", + "integrity": "sha512-0hz44rAcrphyXcA8IS7EJ2SCoaBZD2u5goE8S/e+q/DL+dOGpqpcLidVOFeLG3VgML62SXmfRLAhWt0zL1oW4Q==", + "dev": true, + "dependencies": { + "@inquirer/type": "^1.5.5" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 8" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/@inquirer/type": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", + "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", + "dev": true, + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.1.5.tgz", + "integrity": "sha512-ue5PSOzHMCIYrfvPP/MRS6hsKKLzqqhcdAvJCO8uFlDdj598EhgnacuOTuqA6uBK5rgiZXfDWyb7DVZSiBKxBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.1.5.tgz", + "integrity": "sha512-CGhsb0R5vE6mMNCoSfxHFD8QTvBHM51gs4DBeigTYHWnYv2V5YpJkC4rMo5qAAFifuUcc0+a8a3SIU0c9NrfNw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.1.5.tgz", + "integrity": "sha512-3WeW328DN+xB5PZdhSWmqE+t3+44xWXEbqQ+caWJEZfOFdLp9yklBZEbVqVdqzznkoaXJYxTCp996KD6HmANeg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.1.5.tgz", + "integrity": "sha512-LAjaoOcBHGj6fiYB8ureiqPoph4eygbXu4vcOF+hsxiY74n8ilA7rJMmGUT0K0JOB5lmRQHSmor3mytRjS4qeQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.1.5.tgz", + "integrity": "sha512-k/IklElP70qdCXOQixclSl2GPLFiopynGoKX1FqDd1/H0E3Fo1oPwjY2rEVu+0nS3AOw1sryStdXk8CW3cVIsw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.1.5.tgz", + "integrity": "sha512-KYar6W8nraZfSJspcK7Kp7hdj238X/FNauYbZyrqPBrtsXI1hvI4/KcRcRGP50aQoV7fkKDyJERlrQGMGTZUsA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@napi-rs/nice": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.0.1.tgz", + "integrity": "sha512-zM0mVWSXE0a0h9aKACLwKmD6nHcRiKrPpCfvaKqG1CqDEyjEawId0ocXxVzPMCAm6kkWr2P025msfxXEnt8UGQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/nice-android-arm-eabi": "1.0.1", + "@napi-rs/nice-android-arm64": "1.0.1", + "@napi-rs/nice-darwin-arm64": "1.0.1", + "@napi-rs/nice-darwin-x64": "1.0.1", + "@napi-rs/nice-freebsd-x64": "1.0.1", + "@napi-rs/nice-linux-arm-gnueabihf": "1.0.1", + "@napi-rs/nice-linux-arm64-gnu": "1.0.1", + "@napi-rs/nice-linux-arm64-musl": "1.0.1", + "@napi-rs/nice-linux-ppc64-gnu": "1.0.1", + "@napi-rs/nice-linux-riscv64-gnu": "1.0.1", + "@napi-rs/nice-linux-s390x-gnu": "1.0.1", + "@napi-rs/nice-linux-x64-gnu": "1.0.1", + "@napi-rs/nice-linux-x64-musl": "1.0.1", + "@napi-rs/nice-win32-arm64-msvc": "1.0.1", + "@napi-rs/nice-win32-ia32-msvc": "1.0.1", + "@napi-rs/nice-win32-x64-msvc": "1.0.1" + } + }, + "node_modules/@napi-rs/nice-android-arm-eabi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.1.tgz", + "integrity": "sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-android-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.0.1.tgz", + "integrity": "sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.0.1.tgz", + "integrity": "sha512-91k3HEqUl2fsrz/sKkuEkscj6EAj3/eZNCLqzD2AA0TtVbkQi8nqxZCZDMkfklULmxLkMxuUdKe7RvG/T6s2AA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.1.tgz", + "integrity": "sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-freebsd-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.0.1.tgz", + "integrity": "sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.0.1.tgz", + "integrity": "sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.0.1.tgz", + "integrity": "sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-musl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.0.1.tgz", + "integrity": "sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-ppc64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.0.1.tgz", + "integrity": "sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-riscv64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.0.1.tgz", + "integrity": "sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-s390x-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.0.1.tgz", + "integrity": "sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.0.1.tgz", + "integrity": "sha512-XQAJs7DRN2GpLN6Fb+ZdGFeYZDdGl2Fn3TmFlqEL5JorgWKrQGRUrpGKbgZ25UeZPILuTKJ+OowG2avN8mThBA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-musl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.0.1.tgz", + "integrity": "sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-arm64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.0.1.tgz", + "integrity": "sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-ia32-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.0.1.tgz", + "integrity": "sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-x64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.0.1.tgz", + "integrity": "sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ngtools/webpack": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-19.0.6.tgz", + "integrity": "sha512-eWrIb0tS1CK6+JvFS4GgTD4fN9TtmApKrlaj3pPQXKXKKd42361ec85fuQQXdb4G8eEEq0vyd/bn4NJllh/3vw==", + "dev": true, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^19.0.0", + "typescript": ">=5.5 <5.7", + "webpack": "^5.54.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz", + "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/@npmcli/fs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz", + "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-6.0.1.tgz", + "integrity": "sha512-BBWMMxeQzalmKadyimwb2/VVQyJB01PH0HhVSNLHNBDZN/M/h/02P6f8fxedIiFhpMj11SO9Ep5tKTBE7zL2nw==", + "dev": true, + "dependencies": { + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-3.0.0.tgz", + "integrity": "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q==", + "dev": true, + "dependencies": { + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-6.1.0.tgz", + "integrity": "sha512-t6G+6ZInT4X+tqj2i+wlLIeCKnKOTuz9/VFYDtj+TGTur5q7sp/OYrQA19LdBbWfXDOi0Y4jtedV6xtB8zQ9ug==", + "dev": true, + "dependencies": { + "@npmcli/git": "^6.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "normalize-package-data": "^7.0.0", + "proc-log": "^5.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/package-json/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-8.0.2.tgz", + "integrity": "sha512-/bNJhjc+o6qL+Dwz/bqfTQClkEO5nTQ1ZEcdCkAQjhkZMHIh22LPG7fNh1enJP1NKWDqYiiABnjFCY7E0zHYtQ==", + "dev": true, + "dependencies": { + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-3.0.0.tgz", + "integrity": "sha512-/1uFzjVcfzqrgCeGW7+SZ4hv0qLWmKXVzFahZGJ6QuJBj6Myt9s17+JL86i76NV9YSnJRcGXJYQbAU0rn1YTCQ==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-9.0.2.tgz", + "integrity": "sha512-cJXiUlycdizQwvqE1iaAb4VRUM3RX09/8q46zjvy+ct9GhfZRWd7jXYVc1tn/CfRlGPVkX/u4sstRlepsm7hfw==", + "dev": true, + "dependencies": { + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "node-gyp": "^11.0.0", + "proc-log": "^5.0.0", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.0.tgz", + "integrity": "sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.0", + "@parcel/watcher-darwin-arm64": "2.5.0", + "@parcel/watcher-darwin-x64": "2.5.0", + "@parcel/watcher-freebsd-x64": "2.5.0", + "@parcel/watcher-linux-arm-glibc": "2.5.0", + "@parcel/watcher-linux-arm-musl": "2.5.0", + "@parcel/watcher-linux-arm64-glibc": "2.5.0", + "@parcel/watcher-linux-arm64-musl": "2.5.0", + "@parcel/watcher-linux-x64-glibc": "2.5.0", + "@parcel/watcher-linux-x64-musl": "2.5.0", + "@parcel/watcher-win32-arm64": "2.5.0", + "@parcel/watcher-win32-ia32": "2.5.0", + "@parcel/watcher-win32-x64": "2.5.0" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.0.tgz", + "integrity": "sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.0.tgz", + "integrity": "sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.0.tgz", + "integrity": "sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.0.tgz", + "integrity": "sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.0.tgz", + "integrity": "sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.0.tgz", + "integrity": "sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.0.tgz", + "integrity": "sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.0.tgz", + "integrity": "sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.0.tgz", + "integrity": "sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.0.tgz", + "integrity": "sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.0.tgz", + "integrity": "sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.0.tgz", + "integrity": "sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.0.tgz", + "integrity": "sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@parcel/watcher/node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "optional": true + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.26.0.tgz", + "integrity": "sha512-gJNwtPDGEaOEgejbaseY6xMFu+CPltsc8/T+diUTTbOQLqD+bnrJq9ulH6WD69TqwqWmrfRAtUv30cCFZlbGTQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.26.0.tgz", + "integrity": "sha512-YJa5Gy8mEZgz5JquFruhJODMq3lTHWLm1fOy+HIANquLzfIOzE9RA5ie3JjCdVb9r46qfAQY/l947V0zfGJ0OQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.26.0.tgz", + "integrity": "sha512-ErTASs8YKbqTBoPLp/kA1B1Um5YSom8QAc4rKhg7b9tyyVqDBlQxy7Bf2wW7yIlPGPg2UODDQcbkTlruPzDosw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.26.0.tgz", + "integrity": "sha512-wbgkYDHcdWW+NqP2mnf2NOuEbOLzDblalrOWcPyY6+BRbVhliavon15UploG7PpBRQ2bZJnbmh8o3yLoBvDIHA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.26.0.tgz", + "integrity": "sha512-Y9vpjfp9CDkAG4q/uwuhZk96LP11fBz/bYdyg9oaHYhtGZp7NrbkQrj/66DYMMP2Yo/QPAsVHkV891KyO52fhg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.26.0.tgz", + "integrity": "sha512-A/jvfCZ55EYPsqeaAt/yDAG4q5tt1ZboWMHEvKAH9Zl92DWvMIbnZe/f/eOXze65aJaaKbL+YeM0Hz4kLQvdwg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.26.0.tgz", + "integrity": "sha512-paHF1bMXKDuizaMODm2bBTjRiHxESWiIyIdMugKeLnjuS1TCS54MF5+Y5Dx8Ui/1RBPVRE09i5OUlaLnv8OGnA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.26.0.tgz", + "integrity": "sha512-cwxiHZU1GAs+TMxvgPfUDtVZjdBdTsQwVnNlzRXC5QzIJ6nhfB4I1ahKoe9yPmoaA/Vhf7m9dB1chGPpDRdGXg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.26.0.tgz", + "integrity": "sha512-4daeEUQutGRCW/9zEo8JtdAgtJ1q2g5oHaoQaZbMSKaIWKDQwQ3Yx0/3jJNmpzrsScIPtx/V+1AfibLisb3AMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.26.0.tgz", + "integrity": "sha512-eGkX7zzkNxvvS05ROzJ/cO/AKqNvR/7t1jA3VZDi2vRniLKwAWxUr85fH3NsvtxU5vnUUKFHKh8flIBdlo2b3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.26.0.tgz", + "integrity": "sha512-Odp/lgHbW/mAqw/pU21goo5ruWsytP7/HCC/liOt0zcGG0llYWKrd10k9Fj0pdj3prQ63N5yQLCLiE7HTX+MYw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.26.0.tgz", + "integrity": "sha512-MBR2ZhCTzUgVD0OJdTzNeF4+zsVogIR1U/FsyuFerwcqjZGvg2nYe24SAHp8O5sN8ZkRVbHwlYeHqcSQ8tcYew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.26.0.tgz", + "integrity": "sha512-YYcg8MkbN17fMbRMZuxwmxWqsmQufh3ZJFxFGoHjrE7bv0X+T6l3glcdzd7IKLiwhT+PZOJCblpnNlz1/C3kGQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.26.0.tgz", + "integrity": "sha512-ZuwpfjCwjPkAOxpjAEjabg6LRSfL7cAJb6gSQGZYjGhadlzKKywDkCUnJ+KEfrNY1jH5EEoSIKLCb572jSiglA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.26.0.tgz", + "integrity": "sha512-+HJD2lFS86qkeF8kNu0kALtifMpPCZU80HvwztIKnYwym3KnA1os6nsX4BGSTLtS2QVAGG1P3guRgsYyMA0Yhg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.26.0.tgz", + "integrity": "sha512-WUQzVFWPSw2uJzX4j6YEbMAiLbs0BUysgysh8s817doAYhR5ybqTI1wtKARQKo6cGop3pHnrUJPFCsXdoFaimQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.26.0.tgz", + "integrity": "sha512-D4CxkazFKBfN1akAIY6ieyOqzoOoBV1OICxgUblWxff/pSjCA2khXlASUx7mK6W1oP4McqhgcCsu6QaLj3WMWg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.26.0.tgz", + "integrity": "sha512-2x8MO1rm4PGEP0xWbubJW5RtbNLk3puzAMaLQd3B3JHVw4KcHlmXcO+Wewx9zCoo7EUFiMlu/aZbCJ7VjMzAag==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@schematics/angular": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-19.0.6.tgz", + "integrity": "sha512-HicclmbW/+mlljU7a4PzbyIWG+7tognoL5LsgMFJQUDzJXHNjRt1riL0vk57o8Pcprnz9FheeWZXO1KRhXkQuw==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "19.0.6", + "@angular-devkit/schematics": "19.0.6", + "jsonc-parser": "3.3.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@schematics/angular/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@schematics/angular/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@schematics/angular/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@sigstore/bundle": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-3.0.0.tgz", + "integrity": "sha512-XDUYX56iMPAn/cdgh/DTJxz5RWmqKV4pwvUAEKEWJl+HzKdCd/24wUa9JYNMlDSCb7SUHAdtksxYX779Nne/Zg==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-2.0.0.tgz", + "integrity": "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.2.tgz", + "integrity": "sha512-c6B0ehIWxMI8wiS/bj6rHMPqeFvngFV7cDU/MY+B16P9Z3Mp9k8L93eYZ7BYzSickzuqAQqAq0V956b3Ju6mLw==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-3.0.0.tgz", + "integrity": "sha512-UjhDMQOkyDoktpXoc5YPJpJK6IooF2gayAr5LvXI4EL7O0vd58okgfRcxuaH+YTdhvb5aa1Q9f+WJ0c2sVuYIw==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^14.0.1", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-3.0.0.tgz", + "integrity": "sha512-9Xxy/8U5OFJu7s+OsHzI96IX/OzjF/zj0BSSaWhgJgTqtlBhQIV2xdrQI5qxLD7+CWWDepadnXAxzaZ3u9cvRw==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2", + "tuf-js": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-2.0.0.tgz", + "integrity": "sha512-Ggtq2GsJuxFNUvQzLoXqRwS4ceRfLAJnrIHUDrzAD0GgnOhwujJkKkxM/s5Bako07c3WtAs/sZo5PJq7VHjeDg==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-3.0.1.tgz", + "integrity": "sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==", + "dev": true, + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@tufjs/models/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/cors": { + "version": "2.8.17", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.2.tgz", + "integrity": "sha512-vluaspfvWEtE4vcSDlKRNer52DvOGrB2xv6diXy6UKyKW0lqZiWHGNApSyxOv+8DE5Z27IzVvE7hNkxg7EXIcg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/express/node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/jasmine": { + "version": "5.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.12.13", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.9.17", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", + "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.1.0.tgz", + "integrity": "sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A==", + "dev": true, + "engines": { + "node": ">=14.6.0" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-loader": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", + "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", + "dev": true, + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.3", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.3" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/base64id": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/beasties": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.1.0.tgz", + "integrity": "sha512-+Ssscd2gVG24qRNC+E2g88D+xsQW4xwakWtKAiGEQ3Pw54/FGdyo9RrfxhGhEv6ilFVbB7r3Lgx+QnAxnSpECw==", + "dev": true, + "dependencies": { + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "htmlparser2": "^9.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-media-query-parser": "^0.2.3" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "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==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz", + "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==", + "dev": true, + "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.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz", + "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^4.0.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001690", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", + "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", + "dev": true, + "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/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/chokidar": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "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" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "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/cli-truncate/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "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==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT" + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", + "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.0.2", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/connect": { + "version": "3.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.4.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/copy-anything": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", + "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", + "dev": true, + "dependencies": { + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.1", + "globby": "^14.0.0", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/core-js-compat": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", + "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==", + "dev": true, + "dependencies": { + "browserslist": "^4.24.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cors": { + "version": "2.8.5", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cosmiconfig/node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/cosmiconfig/node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", + "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", + "dev": true, + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "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==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/custom-event": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/date-format": { + "version": "4.0.14", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/di": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.75", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.75.tgz", + "integrity": "sha512-Lf3++DumRE/QmweGjU+ZcKqQ+3bKkU/qjaKYhIJKEOhgIO9Xs6IiAQFkfFoj+RhgDk4LUeNsLo6plExHqSyu6Q==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/engine.io": { + "version": "6.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", + "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ent": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/entities": { + "version": "4.5.0", + "devOptional": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "node_modules/errno": { + "version": "0.1.8", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.3", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz", + "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.0", + "@esbuild/android-arm": "0.24.0", + "@esbuild/android-arm64": "0.24.0", + "@esbuild/android-x64": "0.24.0", + "@esbuild/darwin-arm64": "0.24.0", + "@esbuild/darwin-x64": "0.24.0", + "@esbuild/freebsd-arm64": "0.24.0", + "@esbuild/freebsd-x64": "0.24.0", + "@esbuild/linux-arm": "0.24.0", + "@esbuild/linux-arm64": "0.24.0", + "@esbuild/linux-ia32": "0.24.0", + "@esbuild/linux-loong64": "0.24.0", + "@esbuild/linux-mips64el": "0.24.0", + "@esbuild/linux-ppc64": "0.24.0", + "@esbuild/linux-riscv64": "0.24.0", + "@esbuild/linux-s390x": "0.24.0", + "@esbuild/linux-x64": "0.24.0", + "@esbuild/netbsd-x64": "0.24.0", + "@esbuild/openbsd-arm64": "0.24.0", + "@esbuild/openbsd-x64": "0.24.0", + "@esbuild/sunos-x64": "0.24.0", + "@esbuild/win32-arm64": "0.24.0", + "@esbuild/win32-ia32": "0.24.0", + "@esbuild/win32-x64": "0.24.0" + } + }, + "node_modules/esbuild-wasm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.24.0.tgz", + "integrity": "sha512-xhNn5tL1AhkPg4ft59yXT6FkwKXiPSYyz1IeinJHUJpjvOHOIPvdmFQc0pGdjxlKSbzZc2mNmtVOWAR1EF/JAg==", + "dev": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dev": true, + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/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==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", + "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "function-bind": "^1.1.2", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "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", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "dev": true, + "license": "BSD-2-Clause" + }, + "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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "dev": true, + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.0.2.tgz", + "integrity": "sha512-sYKnA7eGln5ov8T8gnYlkSOxFJvywzEx9BueN6xo/GKO8PGiI6uK6xx+DIGe45T3bdVjLAQDQW1aicT8z8JwQg==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "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==", + "dev": true + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-middleware": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.3.tgz", + "integrity": "sha512-usY0HG5nyDUwtqpiZdETNbmKtw3QQ1jwYFZ9wi5iHzX2BcILwQKtYDJPo7XHTsu5Z0B2Hj3W9NNnbd+AjFWjqg==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.15", + "debug": "^4.3.6", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.3", + "is-plain-object": "^5.0.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-middleware/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-7.0.0.tgz", + "integrity": "sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ==", + "dev": true, + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ignore-walk/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immutable": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "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-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "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": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jasmine-core": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.0", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "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==", + "dev": true + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", + "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/karma": { + "version": "6.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.7.2", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-chrome-launcher": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "which": "^1.2.1" + } + }, + "node_modules/karma-coverage": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.0.5", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/karma-jasmine": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "jasmine-core": "^4.1.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "karma": "^6.0.0" + } + }, + "node_modules/karma-jasmine-html-reporter": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "peerDependencies": { + "jasmine-core": "^4.0.0 || ^5.0.0", + "karma": "^6.0.0", + "karma-jasmine": "^5.0.0" + } + }, + "node_modules/karma-jasmine/node_modules/jasmine-core": { + "version": "4.6.1", + "dev": true, + "license": "MIT" + }, + "node_modules/karma-source-map-support": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map-support": "^0.5.5" + } + }, + "node_modules/karma/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/karma/node_modules/cliui": { + "version": "7.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/karma/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/karma/node_modules/tmp": { + "version": "0.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/karma/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/karma/node_modules/yargs": { + "version": "16.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/karma/node_modules/yargs-parser": { + "version": "20.2.9", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/launch-editor": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/less": { + "version": "4.2.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less-loader": { + "version": "12.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "less": "^3.5.0 || ^4.0.0", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/less/node_modules/make-dir": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/mime": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/less/node_modules/semver": { + "version": "5.7.2", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/less/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/license-webpack-plugin": { + "version": "4.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "webpack-sources": "^3.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-sources": { + "optional": true + } + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", + "integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "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/listr2/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/lmdb": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.1.5.tgz", + "integrity": "sha512-46Mch5Drq+A93Ss3gtbg+Xuvf5BOgIuvhKDWoGa3HcPHI6BL2NCOkRdSx1D4VfzwrxhnsjbyIVsLRlQHu6URvw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "msgpackr": "^1.11.2", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.2.2", + "ordered-binary": "^1.5.3", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "3.1.5", + "@lmdb/lmdb-darwin-x64": "3.1.5", + "@lmdb/lmdb-linux-arm": "3.1.5", + "@lmdb/lmdb-linux-arm64": "3.1.5", + "@lmdb/lmdb-linux-x64": "3.1.5", + "@lmdb/lmdb-win32-x64": "3.1.5" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/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==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "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/log-update/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/log4js": { + "version": "6.9.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-fetch-happen": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", + "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==", + "dev": true, + "dependencies": { + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/make-fetch-happen/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.15.1.tgz", + "integrity": "sha512-ufCzgFwiVnR6R9cCYuvwznJdhdYXEvFl0hpnM4cCtVaVkHuqBR+6fo2sqt1SSMdp+uiHw9GyPZr3OMM5tqjSmQ==", + "dev": true, + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.3.0", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", + "dev": true, + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.0.tgz", + "integrity": "sha512-2v6aXUXwLP1Epd/gc32HAMIWoczx+fZwEPRHm/VwtrJzRGwR1qGZXEYV3Zp8ZjjbwaZhMrM6uHV4KVkk+XCc2w==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/minizlib/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/minizlib/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minizlib/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minizlib/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/msgpackr": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz", + "integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==", + "dev": true, + "optional": true, + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/needle": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "optional": true + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.0.0.tgz", + "integrity": "sha512-zQS+9MTTeCMgY0F3cWPyJyRFAkVltQ1uXm+xXu/ES6KFgC6Czo1Seb9vQW2wNxSX2OrDTiqL0ojtkFxBQ0ypIw==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^14.0.3", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "tar": "^7.4.3", + "which": "^5.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-gyp/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/node-gyp/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/node-gyp/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true + }, + "node_modules/nopt": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.0.0.tgz", + "integrity": "sha512-1L/fTJ4UmV/lUxT2Uf006pfZKTvAgCF+chz+0OgBHO8u2Z67pE7AaAUUj7CJy0lXqHmymUvGFt6NE9R3HER0yw==", + "dev": true, + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/normalize-package-data": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-7.0.0.tgz", + "integrity": "sha512-k6U0gKRIuNCTkwHGZqblCfLfBRh+w1vI6tBo+IeJwq2M8FUiOqhX7GH+GArQGScA7azd1WfyRCvxoXDO3hQDIA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^8.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-bundled": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-4.0.0.tgz", + "integrity": "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA==", + "dev": true, + "dependencies": { + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-install-checks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-7.1.1.tgz", + "integrity": "sha512-u6DCwbow5ynAX5BdiHQ9qvexme4U3qHW3MWe5NqH+NeBm0LbiH6zvGjNNew1fY+AZZUtVHbOPF3j7mJxbUzpXg==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", + "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-package-arg": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.0.tgz", + "integrity": "sha512-ZTE0hbwSdTNL+Stx2zxSqdu2KZfNDcrtrLdIk7XGnQFYBWYDho/ORvXtn5XEePcL3tFpGjHCV3X3xrtDh7eZ+A==", + "dev": true, + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-packlist": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-9.0.0.tgz", + "integrity": "sha512-8qSayfmHJQTx3nJWYbbUmflpyarbLMBc6LCAjYsiGtXxDB68HaZpb8re6zeaLGxZzDuMdhsg70jryJe+RrItVQ==", + "dev": true, + "dependencies": { + "ignore-walk": "^7.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-10.0.0.tgz", + "integrity": "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==", + "dev": true, + "dependencies": { + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-18.0.2.tgz", + "integrity": "sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ==", + "dev": true, + "dependencies": { + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.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==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ordered-binary": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.3.tgz", + "integrity": "sha512-oGFr3T+pYdTGJ+YFEILMpS3es+GiIbs9h/XQrclBXUtd44ey7XwfsMzM31f64I1SQOawDoDr/D823kNCADI8TA==", + "dev": true, + "optional": true + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", + "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, + "node_modules/pacote": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-20.0.0.tgz", + "integrity": "sha512-pRjC5UFwZCgx9kUFDVM9YEahv4guZ1nSLqwmWiLUnDbGsjs+U5w7z6Uc8HNR1a6x8qnu5y9xtGE6D1uAuYz+0A==", + "dev": true, + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "devOptional": true, + "license": "MIT", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz", + "integrity": "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==", + "dev": true, + "dependencies": { + "entities": "^4.3.0", + "parse5": "^7.0.0", + "parse5-sax-parser": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-sax-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", + "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==", + "dev": true, + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true + }, + "node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/picomatch": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/piscina": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.7.0.tgz", + "integrity": "sha512-b8hvkpp9zS0zsfa939b/jXbe64Z2gZv0Ha7FYPNUiDIB1y2AtxcOZdfP8xN8HFjUaqQiT9gRlfjAsoL8vdJ1Iw==", + "dev": true, + "optionalDependencies": { + "@napi-rs/nice": "^1.0.1" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dev": true, + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "dev": true, + "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.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-loader": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cosmiconfig": "^9.0.0", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/punycode": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qjobs": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.9" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-parser": { + "version": "2.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/regexpu-core": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dev": true, + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.8", + "dev": true, + "license": "MIT", + "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-url-loader": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/resolve-url-loader/node_modules/loader-utils": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true + }, + "node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.26.0.tgz", + "integrity": "sha512-ilcl12hnWonG8f+NxU6BlgysVA0gvY2l8N0R84S1HcINbW20bvwuCngJkkInV6LXhwRpucsW5k1ovDwEdBVrNg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.26.0", + "@rollup/rollup-android-arm64": "4.26.0", + "@rollup/rollup-darwin-arm64": "4.26.0", + "@rollup/rollup-darwin-x64": "4.26.0", + "@rollup/rollup-freebsd-arm64": "4.26.0", + "@rollup/rollup-freebsd-x64": "4.26.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.26.0", + "@rollup/rollup-linux-arm-musleabihf": "4.26.0", + "@rollup/rollup-linux-arm64-gnu": "4.26.0", + "@rollup/rollup-linux-arm64-musl": "4.26.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.26.0", + "@rollup/rollup-linux-riscv64-gnu": "4.26.0", + "@rollup/rollup-linux-s390x-gnu": "4.26.0", + "@rollup/rollup-linux-x64-gnu": "4.26.0", + "@rollup/rollup-linux-x64-musl": "4.26.0", + "@rollup/rollup-win32-arm64-msvc": "4.26.0", + "@rollup/rollup-win32-ia32-msvc": "4.26.0", + "@rollup/rollup-win32-x64-msvc": "4.26.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.80.7", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.7.tgz", + "integrity": "sha512-MVWvN0u5meytrSjsU7AWsbhoXi1sc58zADXFllfZzbsBT1GHjjar6JwBINYPRrkx/zqnQ6uqbQuHgE95O+C+eQ==", + "dev": true, + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass-loader": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.3.tgz", + "integrity": "sha512-gosNorT1RCkuCMyihv6FBRR7BMV06oKRAs+l4UMp1mlcVg9rWN6KMmUj3igjQwmYys4mDP3etEYJgiHRbgHCHA==", + "dev": true, + "dependencies": { + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sass/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sax": { + "version": "1.4.1", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.6.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dev": true, + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/sigstore": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-3.0.0.tgz", + "integrity": "sha512-PHMifhh3EN4loMcHCz6l3v/luzgT3za+9f8subGgeMNjbJjzH4Ij/YoX3Gvu+kaouJRIlVdTHHCREADYf+ZteA==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/sign": "^3.0.0", + "@sigstore/tuf": "^3.0.0", + "@sigstore/verify": "^2.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socket.io": { + "version": "4.7.5", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.5.2", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "~4.3.4", + "ws": "~8.11.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "dev": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" + } + }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "dev": true + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, + "node_modules/ssri": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz", + "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "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==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-observable": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "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/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==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/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==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/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==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "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==", + "dev": true + }, + "node_modules/terser": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", + "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "dev": true, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tree-dump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", + "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/tuf-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-3.0.1.tgz", + "integrity": "sha512-+68OP1ZzSF84rTckf3FA95vJ1Zlx/uaXyiiKyPd1pA4rZNkpEvDAKmsu1xUSmbF/chCRYgZ6UZkDwC7PmzmAyA==", + "dev": true, + "dependencies": { + "@tufjs/models": "3.0.1", + "debug": "^4.3.6", + "make-fetch-happen": "^14.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/tuf-js/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/tuf-js/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-assert": { + "version": "1.0.9", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.38", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "dev": true, + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unique-filename": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz", + "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==", + "dev": true, + "dependencies": { + "unique-slug": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/unique-slug": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz", + "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "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.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.0.tgz", + "integrity": "sha512-d7KLgL1LD3U3fgnvWEY1cQXoO/q6EQ1BSz48Sa149V/5zVTAbgmZIpyI8TRi6U9/JNyeYLlTKsEMPtLC27RFUg==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "5.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.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": "*", + "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 + } + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "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" + } + }, + "node_modules/void-elements": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true, + "optional": true + }, + "node_modules/webpack": { + "version": "5.96.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.96.1.tgz", + "integrity": "sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "dev": true, + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.1.0.tgz", + "integrity": "sha512-aQpaN81X6tXie1FoOB7xlMfCsN19pSvRAeYUHOdFWOlhpQ/LlbfTqYwwmEDFV0h8GGuqmCmKmT+pxcUV/Nt2gQ==", + "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.19.2", + "graceful-fs": "^4.2.6", + "html-entities": "^2.4.0", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-subresource-integrity": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "typed-assert": "^1.0.8" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", + "webpack": "^5.12.0" + }, + "peerDependenciesMeta": { + "html-webpack-plugin": { + "optional": true + } + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.11.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zone.js": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.0.tgz", + "integrity": "sha512-9oxn0IIjbCZkJ67L+LkhYWRyAy7axphb3VgE2MBDlOqnmHMPWGYMxJxBYFueFq/JGY2GMwS0rU+UCLunEmy5UA==" + } + } +} diff --git a/examples/angular-cli-19/package.json b/examples/angular-cli-19/package.json new file mode 100644 index 00000000..abdb8a50 --- /dev/null +++ b/examples/angular-cli-19/package.json @@ -0,0 +1,44 @@ +{ + "name": "angular-cli", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "npm run build:dev", + "build:dev": "ng build --configuration development", + "build:prod": "ng build --configuration production", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "dependencies": { + "@angular/animations": "^19.0.5", + "@angular/cdk": "^19.0.4", + "@angular/common": "^19.0.5", + "@angular/compiler": "^19.0.5", + "@angular/core": "^19.0.5", + "@angular/forms": "^19.0.5", + "@angular/platform-browser": "^19.0.5", + "@angular/platform-browser-dynamic": "^19.0.5", + "@angular/router": "^19.0.5", + "@fortawesome/fontawesome-svg-core": "^6.7.2", + "@fortawesome/free-solid-svg-icons": "^6.7.2", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^19.0.6", + "@angular/cli": "~19.0.6", + "@angular/compiler-cli": "^19.0.5", + "@types/jasmine": "~5.1.0", + "@types/node": "^20.10.0", + "jasmine-core": "~5.1.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.6.3" + } +} diff --git a/examples/angular-cli-19/src/app/app-routing.module.ts b/examples/angular-cli-19/src/app/app-routing.module.ts new file mode 100644 index 00000000..20be26e4 --- /dev/null +++ b/examples/angular-cli-19/src/app/app-routing.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { ModalGalleryExampleComponent } from './modal-gallery/modal-gallery.component'; +import { PlainGalleryExampleComponent } from './plain-gallery/plain-gallery.component'; +import { CarouselExampleComponent } from './carousel/carousel.component'; +import { HomeComponent } from './home/home.component'; + +const routes: Routes = [ + { path: '', component: HomeComponent }, + { path: 'carousel', component: CarouselExampleComponent }, + { path: 'modal', component: ModalGalleryExampleComponent }, + { path: 'plain', component: PlainGalleryExampleComponent } +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes)], + exports: [RouterModule] +}) +export class AppRoutingModule {} diff --git a/examples/angular-cli-19/src/app/app.component.html b/examples/angular-cli-19/src/app/app.component.html new file mode 100644 index 00000000..27bca28a --- /dev/null +++ b/examples/angular-cli-19/src/app/app.component.html @@ -0,0 +1,59 @@ + + +

+ + + +

+
+ + +
+

A special thank to all authors of icons used in this library:

+ +
+ +
+

A special thanks to all authors of spinners used in this library:

+ +
diff --git a/examples/angular-cli-19/src/app/app.component.scss b/examples/angular-cli-19/src/app/app.component.scss new file mode 100644 index 00000000..e06277ac --- /dev/null +++ b/examples/angular-cli-19/src/app/app.component.scss @@ -0,0 +1,47 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + + +#main-title { + text-align: center; + width: 100%; +} + +#menu { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + + > .menu-item { + margin-left: 10px; + } +} + +.copyright { + text-align: center; +} + +.margin { + margin-left: 15px; + margin-right: 15px; +} diff --git a/examples/angular-cli-19/src/app/app.component.ts b/examples/angular-cli-19/src/app/app.component.ts new file mode 100644 index 00000000..17a818a5 --- /dev/null +++ b/examples/angular-cli-19/src/app/app.component.ts @@ -0,0 +1,33 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component } from '@angular/core'; + +@Component({ + selector: 'ks-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'], + standalone: false +}) +export class AppComponent {} diff --git a/examples/angular-cli-19/src/app/app.module.ts b/examples/angular-cli-19/src/app/app.module.ts new file mode 100644 index 00000000..5f336573 --- /dev/null +++ b/examples/angular-cli-19/src/app/app.module.ts @@ -0,0 +1,71 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; + +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; +import { CarouselExampleComponent } from './carousel/carousel.component'; +import { PlainGalleryExampleComponent } from './plain-gallery/plain-gallery.component'; +import { ModalGalleryExampleComponent } from './modal-gallery/modal-gallery.component'; +import { NavbarComponent } from './navbar/navbar.component'; +import { HomeComponent } from './home/home.component'; +import { IntroHeaderComponent } from './intro-header/intro-header.component'; + +// ********************** angular-modal-gallery ***************************** +import { GalleryModule } from '@ks89/angular-modal-gallery'; // <----------------- angular-modal-gallery library import +// ************************************************************************** + +// ************************ optional font-awesome 5 ************************ +// to install use both `npm i --save @fortawesome/fontawesome-svg-core` and `npm i --save @fortawesome/free-solid-svg-icons` +import { library, dom } from '@fortawesome/fontawesome-svg-core'; +import { faExternalLinkAlt, faPlus, faTimes, faDownload } from '@fortawesome/free-solid-svg-icons'; +library.add(faExternalLinkAlt, faPlus, faTimes, faDownload); +dom.watch(); // Kicks off the process of finding tags and replacing with +// ************************************************************************* + +@NgModule({ + declarations: [ + AppComponent, + CarouselExampleComponent, + PlainGalleryExampleComponent, + ModalGalleryExampleComponent, + NavbarComponent, + HomeComponent, + IntroHeaderComponent + ], + imports: [ + BrowserModule, + FormsModule, + + AppRoutingModule, + + GalleryModule // <-------------------------------------------- @ks89/angular-modal-gallery module import + ], + providers: [], + bootstrap: [AppComponent] +}) +export class AppModule {} diff --git a/examples/angular-cli-19/src/app/carousel/carousel.component.ts b/examples/angular-cli-19/src/app/carousel/carousel.component.ts new file mode 100644 index 00000000..04785c8a --- /dev/null +++ b/examples/angular-cli-19/src/app/carousel/carousel.component.ts @@ -0,0 +1,567 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component } from '@angular/core'; + +import { AccessibilityConfig, CarouselLibConfig, Image, ImageEvent, ModalGalleryConfig, ModalGalleryRef, ModalGalleryService, ModalLibConfig } from '@ks89/angular-modal-gallery'; + +@Component({ + selector: 'ks-carousel-page', + templateUrl: './carousel.html', + styleUrls: ['./carousel.scss'], + standalone: false +}) +export class CarouselExampleComponent { + imageIndex = 1; + galleryId = 1; + autoPlay = true; + showArrows = true; + showDots = true; + + LIBCONFIG102: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: false + } + }; + LIBCONFIG103: CarouselLibConfig = { + carouselSlideInfinite: false + }; + LIBCONFIG104: CarouselLibConfig = { + carouselDotsConfig: { + visible: false + } + }; + LIBCONFIG105: CarouselLibConfig = { + carouselPlayConfig: { + autoPlay: false, + interval: 5000, + pauseOnHover: true + } + }; + LIBCONFIG106: CarouselLibConfig = { + carouselPlayConfig: { + autoPlay: true, + interval: 10000, + pauseOnHover: false + } + }; + LIBCONFIG107: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 7, + width: 'auto', + maxHeight: '100px' + } + }; + LIBCONFIG113: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 5 + }, + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + } + }; + LIBCONFIG114: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 5, + width: 'auto', + maxHeight: '100px' + }, + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: true + } + }; + LIBCONFIG115: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 5, + width: 'auto', + maxHeight: '100px' + }, + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: false, + modalGalleryEnable: false + } + }; + LIBCONFIG116: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 7, + clickable: false + } + }; + LIBCONFIG117: CarouselLibConfig = { + carouselImageConfig: { + invertSwipe: true + } + }; + LIBCONFIG118: CarouselLibConfig = { + carouselImageConfig: { + description: { + strategy: 2 + } + } + }; + LIBCONFIG119: CarouselLibConfig = { + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + }, + carouselPreviewsConfig: { + visible: true, + number: 5, + width: 'auto', + maxHeight: '200px' + } + }; + LIBCONFIG120: CarouselLibConfig = { + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + }, + carouselPreviewsConfig: { + visible: true, + number: 5, + width: 'auto', + maxHeight: '150px' + } + }; + LIBCONFIG121: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + breakpoints: { + xSmall: 50, + small: 60, + medium: 80, + large: 150, + xLarge: 180 + } + } + }; + LIBCONFIG122: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + breakpoints: { + xSmall: 50, + small: 60, + medium: 70, + large: 80, + xLarge: 100 + } + }, + carouselConfig: { + maxWidth: '500px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + } + }; + LIBCONFIG124: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + breakpoints: { + xSmall: 50, + small: 60, + medium: 70, + large: 80, + xLarge: 100 + } + }, + carouselConfig: { + maxWidth: '500px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + }, + carouselPlayConfig: { + autoPlay: false, + interval: 1, + pauseOnHover: true + } + }; + + imagesRect: Image[] = [ + new Image( + 0, + { + img: '/assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1' + }, + { + img: '/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', + title: 'First image title', + alt: 'First image alt', + ariaLabel: 'First image aria-label' + } + ), + new Image(1, { img: '/assets/images/gallery/pexels-photo-47223.jpeg' }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg' }), + new Image( + 2, + { + img: '/assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3', + title: 'Third image title', + alt: 'Third image alt', + ariaLabel: 'Third image aria-label' + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '/assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4', + title: 'Fourth image title (modal obj)', + alt: 'Fourth image alt (modal obj)', + ariaLabel: 'Fourth image aria-label (modal obj)' + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', + title: 'Fourth image title (plain obj)', + alt: 'Fourth image alt (plain obj)', + ariaLabel: 'Fourth image aria-label (plain obj)' + } + ), + new Image(4, { img: '/assets/images/gallery/pexels-photo-93750.jpeg' }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg' }), + new Image( + 5, + { + img: '/assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6' + }, + { img: '/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg' } + ), + new Image(6, { img: '/assets/images/gallery/pexels-photo-96947.jpeg' }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg' }) + ]; + + imagesRectWithSources: Image[] = [ + new Image( + 0, + { + img: '/assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/milan-pegasus-gallery-statue-480w.jpg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/milan-pegasus-gallery-statue-768w.jpg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/milan-pegasus-gallery-statue-1024w.jpg' } + ] + }, + { + img: '/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', + title: 'First image title', + alt: 'First image alt', + ariaLabel: 'First image aria-label' + } + ), + new Image(1, { img: '/assets/images/gallery/pexels-photo-47223.jpeg', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-47223-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-47223-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-47223-1024w.jpeg' } + ] }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg' }), + new Image( + 2, + { + img: '/assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3', + title: 'Third image title', + alt: 'Third image alt', + ariaLabel: 'Third image aria-label', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-52062-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-52062-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-52062-1024w.jpeg' } + ] + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '/assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4', + title: 'Fourth image title (modal obj)', + alt: 'Fourth image alt (modal obj)', + ariaLabel: 'Fourth image aria-label (modal obj)', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-66943-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-66943-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-66943-1024w.jpeg' } + ] + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', + title: 'Fourth image title (plain obj)', + alt: 'Fourth image alt (plain obj)', + ariaLabel: 'Fourth image aria-label (plain obj)' + } + ), + new Image(4, { img: '/assets/images/gallery/pexels-photo-93750.jpeg', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-93750-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-93750-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-93750-1024w.jpeg' } + ] }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg' }), + new Image( + 5, + { + img: '/assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-94420-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-94420-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-94420-1024w.jpeg' } + ] + }, + { img: '/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg' } + ), + new Image(6, { img: '/assets/images/gallery/pexels-photo-96947.jpeg', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-96947-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-96947-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-96947-1024w.jpeg' } + ] }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg' }) + ]; + + emptyImagesArray: Image[] = []; + + imagesRectNoTitles: Image[] = [ + new Image( + 0, + { img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', title: '' } + ), + new Image( + 1, + { img: '../assets/images/gallery/pexels-photo-47223.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg', title: '' } + ), + new Image( + 2, + { img: '../assets/images/gallery/pexels-photo-52062.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', title: '' } + ), + new Image( + 3, + { img: '../assets/images/gallery/pexels-photo-66943.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', title: '' } + ), + new Image( + 4, + { img: '../assets/images/gallery/pexels-photo-93750.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg', title: '' } + ), + new Image( + 5, + { img: '../assets/images/gallery/pexels-photo-94420.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg', title: '' } + ), + new Image( + 6, + { img: '../assets/images/gallery/pexels-photo-96947.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg', title: '' } + ) + ]; + + fallbackRectImages: Image[] = [ + new Image(0, { + // this file is not available so the browser returns an error + img: '../assets/images/gallery/UNEXISTING_IMG1.jpg', + // because the img above doesn't exists, the library will use this file + fallbackImg: '../assets/images/gallery/fallback-carousel1.jpg' + }), + new Image(1, { + img: '../assets/images/gallery/UNEXISTING_IMG2.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel2.jpg' + }), + new Image( + 2, + { + img: '../assets/images/gallery/UNEXISTING_IMG3.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel3.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG3.png', + fallbackImg: '../assets/images/gallery/fallback-carousel3.jpg' + } + ), + new Image(3, { + img: '../assets/images/gallery/UNEXISTING_IMG4.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel4.jpg' + }), + new Image( + 4, + { + img: '../assets/images/gallery/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel5.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel5.jpg' + } + ) + ]; + + accessibilityConfig: AccessibilityConfig = { + backgroundAriaLabel: 'CUSTOM Modal gallery full screen background', + backgroundTitle: 'CUSTOM background title', + + plainGalleryContentAriaLabel: 'CUSTOM Plain gallery content', + plainGalleryContentTitle: 'CUSTOM plain gallery content title', + + modalGalleryContentAriaLabel: 'CUSTOM Modal gallery content', + modalGalleryContentTitle: 'CUSTOM modal gallery content title', + + loadingSpinnerAriaLabel: 'CUSTOM The current image is loading. Please be patient.', + loadingSpinnerTitle: 'CUSTOM The current image is loading. Please be patient.', + + mainContainerAriaLabel: 'CUSTOM Current image and navigation', + mainContainerTitle: 'CUSTOM main container title', + mainPrevImageAriaLabel: 'CUSTOM Previous image', + mainPrevImageTitle: 'CUSTOM Previous image', + mainNextImageAriaLabel: 'CUSTOM Next image', + mainNextImageTitle: 'CUSTOM Next image', + + dotsContainerAriaLabel: 'CUSTOM Image navigation dots', + dotsContainerTitle: 'CUSTOM dots container title', + dotAriaLabel: 'CUSTOM Navigate to image number', + + previewsContainerAriaLabel: 'CUSTOM Image previews', + previewsContainerTitle: 'CUSTOM previews title', + previewScrollPrevAriaLabel: 'CUSTOM Scroll previous previews', + previewScrollPrevTitle: 'CUSTOM Scroll previous previews', + previewScrollNextAriaLabel: 'CUSTOM Scroll next previews', + previewScrollNextTitle: 'CUSTOM Scroll next previews', + + carouselContainerAriaLabel: 'Current image and navigation', + carouselContainerTitle: '', + carouselPrevImageAriaLabel: 'Previous image', + carouselPrevImageTitle: 'Previous image', + carouselNextImageAriaLabel: 'Next image', + carouselNextImageTitle: 'Next image', + carouselPreviewsContainerAriaLabel: 'Image previews', + carouselPreviewsContainerTitle: '', + carouselPreviewScrollPrevAriaLabel: 'Scroll previous previews', + carouselPreviewScrollPrevTitle: 'Scroll previous previews', + carouselPreviewScrollNextAriaLabel: 'Scroll next previews', + carouselPreviewScrollNextTitle: 'Scroll next previews' + }; + + constructor(private modalGalleryService: ModalGalleryService) {} + + addRandomImage(): void { + const imageToCopy: Image = this.imagesRect[Math.floor(Math.random() * this.imagesRect.length)]; + const newImage: Image = new Image(this.imagesRect.length - 1 + 1, imageToCopy.modal, imageToCopy.plain); + this.imagesRect = [...this.imagesRect, newImage]; + } + + onChangeAutoPlay(): void { + this.autoPlay = !this.autoPlay; + } + + onChangeShowArrows(): void { + this.showArrows = !this.showArrows; + } + + onChangeShowDots(): void { + this.showDots = !this.showDots; + } + + // output evets + onShow(event: ImageEvent): void { + console.log('show', event); + } + + onFirstImage(event: ImageEvent): void { + console.log('firstImage', event); + } + + onLastImage(event: ImageEvent): void { + console.log('lastImage', event); + } + + getLibConfig108(autoPlay: boolean, showArrows: boolean, showDots: boolean): CarouselLibConfig { + return { + carouselDotsConfig: { + visible: showDots + }, + carouselPlayConfig: { + autoPlay: autoPlay, + interval: 3000, + pauseOnHover: true + }, + carouselConfig: { + maxWidth: '100%', + maxHeight: '400px', + showArrows: showArrows, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + } + } as CarouselLibConfig; + } + + openModal(imageIndex: number, id: number): void { + const imageToShow: Image = this.imagesRect[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: this.imagesRect, + currentImage: imageToShow + } as ModalGalleryConfig) as ModalGalleryRef; + } +} diff --git a/examples/angular-cli-19/src/app/carousel/carousel.html b/examples/angular-cli-19/src/app/carousel/carousel.html new file mode 100644 index 00000000..ee04ac8c --- /dev/null +++ b/examples/angular-cli-19/src/app/carousel/carousel.html @@ -0,0 +1,215 @@ +

Carousel

+
+ +

Basic examples

+
+
+

A1 - (id=100) - carousel example (minimal with all defaults) without content projection

+
+ +
+
+
+

A2 - (id=101) - carousel example (minimal with all defaults)

+
+ +
This is my projected content!
+
+
+
+
+

A3 - (id=102) - carousel example without previews

+
+ +
This is my projected content!
+
+
+
+
+

A4 - (id=103) - carousel example without infinite sliding

+
+ +
This is my projected content!
+
+
+
+
+

A5 - (id=104) - carousel example without dots

+
+ +
This is my projected content!
+
+
+
+
+

A6 - (id=105) - carousel example without auto-play (but all other playConfig properties have default values)

+
+ +
This is my projected content!
+
+
+
+
+

A7 - (id=106) - carousel example with a custom playConfig (10s of interval and pauseOnHover disabled)

+
+ +
This is my projected content!
+
+
+
+
+

A8 - (id=107) - carousel example with a custom previewConfig (7 previews with 'auto' width and 100px of height)

+
+ +
This is my projected content!
+
+
+
+
+

A9 - (id=108) - carousel example with buttons to enable/disable autoplay, arrows and other properties

+

Autoplay:

+

Show Arrows:

+

Show Dots:

+
+ +
This is my projected content!
+
+
+
+
+

A10 - (id=109) - carousel example (minimal with all defaults) with outputs

+
+ +
+
+
+

A11 - (id=110) - carousel example with fallback images when it's not possible to load normal images (to fix issue #194)

+
+ +
+
+
+

A12 - (id=111) - carousel example without title attribute on images

+
+ +
+
+
+

A13 - (id=112) - carousel example with an empty images array.

+

Carousel component doesn't support empty images arrays! To prevent runtime errors, you should use an *ngIf to remove the carousel when there are no images.

+
+ +
+
+
+ +

Examples with custom style

+
+

B1 - (id=113) - carousel example with fixed maxWidth (766px) and custom previews

+

By default, on bigger screen, previews will have height = 200px. If you want you can customize it or also change all breakpoint widths.

+
+ +
This is my projected content!
+
+
+
+
+

B2 - (id=114) - carousel example with fixed maxWidth (766px), custom previews and open modal on click

+
+ +
This is my projected content!
+
+
+
+
+

B3 - (id=115) - carousel example with fixed maxWidth (766px), custom previews and keyboard navigation disabled (for example left/right arrows)

+
+ +
This is my projected content!
+
+
+
+
+

B4 - (id=116) - carousel example with 7 images and unclickable previews

+
+ +
This is my projected content!
+
+
+
+
+ +

Examples with custom current image

+
+

C1 - (id=117) - carousel example with invert swipe on touchscreen devices

+
+ +
This is my projected content!
+
+
+
+
+

C2 - (id=118) - carousel example with description

+
+ +
This is my projected content!
+
+
+
+ + +

Examples with custom previews height

+

I know that these examples look bad, but the purpose is to show only how the library handles heights. + In both examples I didn't set breakpoints, so it will be used default values, but with the maxHeight specified

+

If F1, the maxHeight is 200px, but also the default breakpoints has 200px as maximum size, so the result will be very bad on bigger screen. + In F2, I'm using a smaller maxHeight, so previews won't be taller than 150px, despite the default breakpoints on bigger screens (200px).

+
+

F1 - (id=119) - carousel example with fixed maxWidth (766px) and custom previews (maxHeight 200px)

+
+ +
This is my projected content!
+
+
+
+
+

F2 - (id=120) - carousel example with fixed maxWidth (766px) and custom previews (maxHeight 150px)

+
+ +
This is my projected content!
+
+
+
+ + +

Examples with custom heights for previews (to try responsiveness)

+
+
+

G1 - (id=121) - carousel example (previews with different heights based on the window's width: xSmall: 50, small: 60, medium: 80, large: 150, xLarge: 180)

+
+ +
+
+
+

G2 - (id=122) - carousel example with fixed maxWidth (500px) (previews with different heights based on the window's width: xSmall: 50, small: 60, medium: 70, large: 80, xLarge: 100)

+
+ +
+
+

Examples using sources (to improve LCP)

+
+
+

H1 - (id=123) - carousel example (minimal with all defaults) without content projection - using sources

+
+ +
+
+

H2 - (id=124) - carousel example with fixed maxWidth (500px) (previews with different heights based on the window's width: xSmall: 50, small: 60, medium: 70, large: 80, xLarge: 100) - using sources

+
+ +
+
+
diff --git a/examples/angular-cli-19/src/app/carousel/carousel.scss b/examples/angular-cli-19/src/app/carousel/carousel.scss new file mode 100644 index 00000000..547c14f9 --- /dev/null +++ b/examples/angular-cli-19/src/app/carousel/carousel.scss @@ -0,0 +1,157 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +:host { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; +} + +section { + width: 100%; +} + +h2, h3, p { + margin-left: 20px; +} + +$text-color: #fff; +$background: rgba(0, 0, 0, .7); + +.my-app-custom-plain-container-row { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + .my-app-custom-image-row { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-column { + align-items: center; + display: flex; + flex-direction: column; + justify-content: flex-start; + + .my-app-custom-image-column { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-with-desc { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + figure { + margin: 0; + position: relative; + + img { + max-width: 100%; + height: auto; + cursor: pointer; + } + + figcaption { + background: rgba(0, 0, 0, .5); + color: #fff; + font-size: 85%; + padding: 5px; + position: absolute; + bottom: 3px; + left: 0; + right: 0; + } + } + + .description { + font-weight: bold; + text-align: center; + } + + .my-app-custom-image-with-desc { + height: auto; + margin-right: 2px; + width: 200px; + align-self: start; + } +} + +.more { + background: $background; + cursor: pointer; + color: $text-color; + padding-top: 4px; + height: 46px; + position: absolute; + text-align: center; + width: 50px; +} + + +.projected { + color: white; + font-weight: 600; + font-size: 24px; + text-align: center; + position: absolute; + top: 50%; + width: 100%; + pointer-events: none; +} + +.title { + margin-top: 40px; +} diff --git a/examples/angular-cli-19/src/app/home/home.component.ts b/examples/angular-cli-19/src/app/home/home.component.ts new file mode 100644 index 00000000..82d07f20 --- /dev/null +++ b/examples/angular-cli-19/src/app/home/home.component.ts @@ -0,0 +1,33 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component } from '@angular/core'; + +@Component({ + selector: 'ks-home-page', + templateUrl: './home.html', + styleUrls: ['./home.scss'], + standalone: false +}) +export class HomeComponent {} diff --git a/examples/angular-cli-19/src/app/home/home.html b/examples/angular-cli-19/src/app/home/home.html new file mode 100644 index 00000000..f5ec1261 --- /dev/null +++ b/examples/angular-cli-19/src/app/home/home.html @@ -0,0 +1,12 @@ + +
+ +
+

Welcome

+

This is the official live example of @ks89/angular-modal-gallery. + To get started quickly you can try and check the sourcecode of this example.

+

If you need the full documentation with all apis, this is the official documentation website.

+ +

The official documentation is available at ks89.github.io/angular-modal-gallery-2024-v13.github.io

+
+ diff --git a/examples/angular-cli-19/src/app/home/home.scss b/examples/angular-cli-19/src/app/home/home.scss new file mode 100644 index 00000000..8c5e86a7 --- /dev/null +++ b/examples/angular-cli-19/src/app/home/home.scss @@ -0,0 +1,26 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +.container { + margin-left: 15px; + margin-right: 15px; +} diff --git a/examples/angular-cli-19/src/app/intro-header/intro-header.component.ts b/examples/angular-cli-19/src/app/intro-header/intro-header.component.ts new file mode 100644 index 00000000..c2b1e55b --- /dev/null +++ b/examples/angular-cli-19/src/app/intro-header/intro-header.component.ts @@ -0,0 +1,33 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { Component } from '@angular/core'; + +@Component({ + selector: 'ks-intro-header', + templateUrl: 'intro-header.html', + styleUrls: ['intro-header.scss'], + standalone: false +}) +export class IntroHeaderComponent {} diff --git a/examples/angular-cli-19/src/app/intro-header/intro-header.html b/examples/angular-cli-19/src/app/intro-header/intro-header.html new file mode 100644 index 00000000..94cdd372 --- /dev/null +++ b/examples/angular-cli-19/src/app/intro-header/intro-header.html @@ -0,0 +1,8 @@ +
+ @ks89/angular-modal-gallery icon +

@ks89/angular-modal-gallery

+

Image gallery for Angular >=19

+

Currently v13

+
+
diff --git a/examples/angular-cli-19/src/app/intro-header/intro-header.scss b/examples/angular-cli-19/src/app/intro-header/intro-header.scss new file mode 100644 index 00000000..e0eeaf88 --- /dev/null +++ b/examples/angular-cli-19/src/app/intro-header/intro-header.scss @@ -0,0 +1,73 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// search all occurrences in all code, also html, because it's everywhere +$color-primary: #101010; +$color-secondary: #9e9e9e; +$color-white: #FFF; +$color-black: #000; +$color-light-black: #343A40; +$color-code: #c100e0; +$color-url: #0060b7; +$color-warning: #880012; + +//$font-huge: 24px; +$font-big: 18px; +$font-middle: 14px; +$font-small: 12px; +$font-very-small: 10px; + +.intro-header { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + background-color: $color-primary; + background: linear-gradient(135deg, $color-primary, $color-secondary); + margin-top: 10px; + padding-bottom: 1px; + color: $color-white; + + h1 { + color: $color-white; + font-size: 3rem; + } +} + +.project-title { + margin-top: 20px; + font-size: 2.8rem; + text-align: center; +} + +img { + margin-top: 25px; + border-radius: 10px +} + +.lead { + font-size: 1rem; + text-align: center; + color: #d4d4d4; +} diff --git a/examples/angular-cli-19/src/app/modal-gallery/libconfigs.ts b/examples/angular-cli-19/src/app/modal-gallery/libconfigs.ts new file mode 100644 index 00000000..fdf8c729 --- /dev/null +++ b/examples/angular-cli-19/src/app/modal-gallery/libconfigs.ts @@ -0,0 +1,583 @@ +import { + ButtonsStrategy, + ButtonType, + Description, + DescriptionStrategy, + KS_DEFAULT_BTN_CLOSE, + KS_DEFAULT_BTN_DELETE, + KS_DEFAULT_BTN_DOWNLOAD, + KS_DEFAULT_BTN_EXTURL, + KS_DEFAULT_BTN_FULL_SCREEN, + LoadingConfig, + LoadingType, + ModalLibConfig, + Size +} from '@ks89/angular-modal-gallery'; + +const DEFAULT_SIZE_PREVIEWS: Size = { + width: '100px', + height: 'auto' +}; + +// Examples A +export const LIBCONFIG_406: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: true, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +export const LIBCONFIG_407: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: false, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +export const LIBCONFIG_408: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: false, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +// Examples B +export const LIBCONFIG_500: ModalLibConfig = { + previewConfig: { + visible: false + }, + dotsConfig: { + visible: false + } +}; + +export const LIBCONFIG_501: ModalLibConfig = { + buttonsConfig: { + visible: false, + strategy: ButtonsStrategy.DEFAULT + }, + previewConfig: { + visible: false + }, + dotsConfig: { + visible: false + } +}; + +export const LIBCONFIG_502: ModalLibConfig = { + buttonsConfig: { + visible: false, + strategy: ButtonsStrategy.DEFAULT + }, + slideConfig: { + infinite: false, + sidePreviews: { + show: false, + size: DEFAULT_SIZE_PREVIEWS + } + }, + previewConfig: { + visible: false + }, + dotsConfig: { + visible: false + } +}; + +export const LIBCONFIG_503: ModalLibConfig = { + previewConfig: { + visible: true, + size: { + width: '90px', + height: 'auto' + } + } +}; + +export const LIBCONFIG_504: ModalLibConfig = { + enableCloseOutside: false +}; + +export const LIBCONFIG_505: ModalLibConfig = { + currentImageConfig: { downloadable: false }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.DEFAULT + } +}; + +export const LIBCONFIG_506: ModalLibConfig = { + currentImageConfig: { downloadable: true }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.DEFAULT + } +}; + +export const LIBCONFIG_507: ModalLibConfig = { + currentImageConfig: { downloadable: true }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.SIMPLE + } +}; + +export const LIBCONFIG_508: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: false, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +export const LIBCONFIG_509: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: true, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +export const LIBCONFIG_510: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: false, + type: LoadingType.STANDARD + } + } +}; +export const LIBCONFIG_511: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.STANDARD + } + } +}; +export const LIBCONFIG_512: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.CIRCULAR + } + } +}; +export const LIBCONFIG_513: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.BARS + } + } +}; +export const LIBCONFIG_514: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.DOTS + } + } +}; +export const LIBCONFIG_515: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.CUBE_FLIPPING + } + } +}; +export const LIBCONFIG_516: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.CIRCLES + } + } +}; +export const LIBCONFIG_517: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.EXPLOSING_SQUARES + } + } +}; + +export const LIBCONFIG_518: ModalLibConfig = { + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.DEFAULT + } +}; +export const LIBCONFIG_519: ModalLibConfig = { + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.SIMPLE + } +}; +export const LIBCONFIG_520: ModalLibConfig = { + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.ADVANCED + } +}; +export const LIBCONFIG_521: ModalLibConfig = { + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.FULL + } +}; + +// default buttons but extUrl will open the link in a new tab instead of the current one +// this requires to specify all buttons manually (also if they are not really custom) +export const LIBCONFIG_522: ModalLibConfig = { + currentImageConfig: { downloadable: true }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.CUSTOM, + buttons: [ + { + className: 'ext-url-image', + type: ButtonType.EXTURL, + extUrlInNewTab: true // <--- this is the important thing to understand this example + }, + { + className: 'download-image', + type: ButtonType.DOWNLOAD + }, + { + className: 'close-image', + type: ButtonType.CLOSE + } + ] + } +}; + +export const LIBCONFIG_523: ModalLibConfig = { + currentImageConfig: { + downloadable: true + }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.CUSTOM, + buttons: [ + // KS_DEFAULT_BTN_ROTATE, + KS_DEFAULT_BTN_FULL_SCREEN, + KS_DEFAULT_BTN_DELETE, + KS_DEFAULT_BTN_EXTURL, + KS_DEFAULT_BTN_DOWNLOAD, + KS_DEFAULT_BTN_CLOSE + ] + } +}; + +export const LIBCONFIG_524: ModalLibConfig = { + currentImageConfig: { + downloadable: true + }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.CUSTOM, + buttons: [ + { + className: 'fas fa-plus white', + type: ButtonType.CUSTOM, + ariaLabel: 'custom plus aria label', + title: 'custom plus title', + fontSize: '20px' + }, + { + className: 'fas fa-times white', + type: ButtonType.CLOSE, + ariaLabel: 'custom close aria label', + title: 'custom close title', + fontSize: '20px' + }, + { + className: 'fas fa-download white', + type: ButtonType.DOWNLOAD, + ariaLabel: 'custom download aria label', + title: 'custom download title', + fontSize: '20px' + }, + { + className: 'fas fa-external-link-alt white', + type: ButtonType.EXTURL, + ariaLabel: 'custom exturl aria label', + title: 'custom exturl title', + fontSize: '20px' + } + ] + } +}; + +export const LIBCONFIG_525: ModalLibConfig = { + previewConfig: { + visible: true, + mobileVisible: true + } +}; + +// Examples C +export const LIBCONFIG_600: ModalLibConfig = { + keyboardConfig: { + esc: 'KeyQ', + left: 'ArrowDown', + right: 'ArrowUp' + } +}; + +export const LIBCONFIG_601: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + imageText: 'Look this image ', + numberSeparator: ' of ', + beforeTextDescription: ' => ' + } + } +}; + +export const LIBCONFIG_602: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.HIDE_IF_EMPTY, + imageText: 'Look this image ', + numberSeparator: ' of ', + beforeTextDescription: ' => ' + } + } +}; + +export const LIBCONFIG_603: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_HIDDEN, + // you should build this value programmatically with the result of (show)="..()" event + customFullDescription: 'Custom description of the current visible image' + // if customFullDescription !== undefined, all other fields will be ignored + // imageText: '', + // numberSeparator: '', + // beforeTextDescription: '', + } + } +}; + +export const LIBCONFIG_604: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + // you should build this value programmatically with the result of (show)="..()" event + customFullDescription: 'Custom description of the current visible image' + // if customFullDescription !== undefined, all other fields will be ignored + // imageText: '', + // numberSeparator: '', + // beforeTextDescription: '', + } + } +}; + +export const LIBCONFIG_605: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + imageText: 'Look this image ', + numberSeparator: ' of ', + beforeTextDescription: ' => ' + } + } +}; + +export const LIBCONFIG_606: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + imageText: 'Look this image ', + numberSeparator: ' of ', + beforeTextDescription: ' => ', + style: { + bgColor: 'rgba(255,0,0,.5)', + textColor: 'blue', + marginTop: '3px', + marginBottom: '0px', + marginLeft: '5px', + marginRight: '5px', + position: 'absolute', + top: '0px', + height: '25px' + // be careful to use width, in particular with % values + } + } + } +}; + +export const LIBCONFIG_607: ModalLibConfig = { + previewConfig: { + visible: true, + number: 1 + } +}; + +export const LIBCONFIG_608: ModalLibConfig = { + previewConfig: { + visible: true, + number: 5 + } +}; + +export const LIBCONFIG_609: ModalLibConfig = { + previewConfig: { + visible: true, + arrows: false + } +}; + +export const LIBCONFIG_610: ModalLibConfig = { + previewConfig: { + visible: true, + clickable: false + } +}; + +export const LIBCONFIG_611: ModalLibConfig = { + previewConfig: { + visible: true, + size: { width: '30px', height: '30px' } + } +}; + +export const LIBCONFIG_612: ModalLibConfig = { + accessibilityConfig: { + backgroundAriaLabel: 'CUSTOM Modal gallery full screen background', + backgroundTitle: 'CUSTOM background title', + + plainGalleryContentAriaLabel: 'CUSTOM Plain gallery content', + plainGalleryContentTitle: 'CUSTOM plain gallery content title', + + modalGalleryContentAriaLabel: 'CUSTOM Modal gallery content', + modalGalleryContentTitle: 'CUSTOM modal gallery content title', + + loadingSpinnerAriaLabel: 'CUSTOM The current image is loading. Please be patient.', + loadingSpinnerTitle: 'CUSTOM The current image is loading. Please be patient.', + + mainContainerAriaLabel: 'CUSTOM Current image and navigation', + mainContainerTitle: 'CUSTOM main container title', + mainPrevImageAriaLabel: 'CUSTOM Previous image', + mainPrevImageTitle: 'CUSTOM Previous image', + mainNextImageAriaLabel: 'CUSTOM Next image', + mainNextImageTitle: 'CUSTOM Next image', + + dotsContainerAriaLabel: 'CUSTOM Image navigation dots', + dotsContainerTitle: 'CUSTOM dots container title', + dotAriaLabel: 'CUSTOM Navigate to image number', + + previewsContainerAriaLabel: 'CUSTOM Image previews', + previewsContainerTitle: 'CUSTOM previews title', + previewScrollPrevAriaLabel: 'CUSTOM Scroll previous previews', + previewScrollPrevTitle: 'CUSTOM Scroll previous previews', + previewScrollNextAriaLabel: 'CUSTOM Scroll next previews', + previewScrollNextTitle: 'CUSTOM Scroll next previews', + + carouselContainerAriaLabel: 'Current image and navigation', + carouselContainerTitle: '', + carouselPrevImageAriaLabel: 'Previous image', + carouselPrevImageTitle: 'Previous image', + carouselNextImageAriaLabel: 'Next image', + carouselNextImageTitle: 'Next image', + carouselPreviewsContainerAriaLabel: 'Image previews', + carouselPreviewsContainerTitle: '', + carouselPreviewScrollPrevAriaLabel: 'Scroll previous previews', + carouselPreviewScrollPrevTitle: 'Scroll previous previews', + carouselPreviewScrollNextAriaLabel: 'Scroll next previews', + carouselPreviewScrollNextTitle: 'Scroll next previews' + } +}; + +export const LIBCONFIG_613: ModalLibConfig = { + currentImageConfig: { + navigateOnClick: false + } +}; + +// Examples D +export const LIBCONFIG_701: ModalLibConfig = { + currentImageConfig: { + downloadable: true + }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.SIMPLE + } +}; + +export const LIBCONFIG_702: ModalLibConfig = { + currentImageConfig: { + invertSwipe: true + } +}; + +export const LIBCONFIG_703: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: true, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +// Examples E +export const LIBCONFIG_800: ModalLibConfig = { + slideConfig: { + playConfig: { + autoPlay: true, + interval: 5000, + pauseOnHover: true + } + } +}; + +export const LIBCONFIG_801: ModalLibConfig = { + slideConfig: { + infinite: true, + playConfig: { + autoPlay: true, + interval: 5000, + pauseOnHover: false + } + } +}; + +export const LIBCONFIG_802: ModalLibConfig = { + slideConfig: { + playConfig: { + autoPlay: true, + interval: 1000, + pauseOnHover: false + } + } +}; + +// Examples F +export const LIBCONFIG_900: ModalLibConfig = { + slideConfig: { + infinite: false + }, + currentImageConfig: { + loadingConfig: { enable: true, type: LoadingType.STANDARD } as LoadingConfig, + description: { strategy: DescriptionStrategy.ALWAYS_VISIBLE } as Description + } +}; diff --git a/examples/angular-cli-19/src/app/modal-gallery/modal-gallery.component.ts b/examples/angular-cli-19/src/app/modal-gallery/modal-gallery.component.ts new file mode 100644 index 00000000..303d2977 --- /dev/null +++ b/examples/angular-cli-19/src/app/modal-gallery/modal-gallery.component.ts @@ -0,0 +1,763 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { TemplateRef } from '@angular/core'; +import { ViewChild } from '@angular/core'; +import { Component, OnDestroy } from '@angular/core'; +import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; + +import { + Action, + ButtonEvent, + ButtonType, + Image, + ImageModalEvent, + ModalGalleryService, + ModalGalleryRef, + ModalGalleryConfig, + ModalLibConfig +} from '@ks89/angular-modal-gallery'; +import { Subscription } from 'rxjs'; + +import * as libConfigs from './libconfigs'; + +@Component({ + selector: 'ks-modal-gallery-page', + templateUrl: './modal-gallery.html', + styleUrls: ['./modal-gallery.scss'], + standalone: false +}) +export class ModalGalleryExampleComponent implements OnDestroy { + /** + * A custom template to illustrate the customization of previews rendering. + */ + @ViewChild('previewsTemplate') + previewsTemplate?: TemplateRef; + + imageIndex = 0; + galleryId = 1; + isPlaying = true; + // Examples A + CONFIG406: ModalLibConfig = libConfigs.LIBCONFIG_406; + CONFIG407: ModalLibConfig = libConfigs.LIBCONFIG_407; + CONFIG408: ModalLibConfig = libConfigs.LIBCONFIG_408; + // Examples B + CONFIG500: ModalLibConfig = libConfigs.LIBCONFIG_500; + CONFIG501: ModalLibConfig = libConfigs.LIBCONFIG_501; + CONFIG502: ModalLibConfig = libConfigs.LIBCONFIG_502; + CONFIG503: ModalLibConfig = libConfigs.LIBCONFIG_503; + CONFIG504: ModalLibConfig = libConfigs.LIBCONFIG_504; + CONFIG505: ModalLibConfig = libConfigs.LIBCONFIG_505; + CONFIG506: ModalLibConfig = libConfigs.LIBCONFIG_506; + CONFIG507: ModalLibConfig = libConfigs.LIBCONFIG_507; + CONFIG508: ModalLibConfig = libConfigs.LIBCONFIG_508; + CONFIG509: ModalLibConfig = libConfigs.LIBCONFIG_509; + CONFIG510: ModalLibConfig = libConfigs.LIBCONFIG_510; + CONFIG511: ModalLibConfig = libConfigs.LIBCONFIG_511; + CONFIG512: ModalLibConfig = libConfigs.LIBCONFIG_512; + CONFIG513: ModalLibConfig = libConfigs.LIBCONFIG_513; + CONFIG514: ModalLibConfig = libConfigs.LIBCONFIG_514; + CONFIG515: ModalLibConfig = libConfigs.LIBCONFIG_515; + CONFIG516: ModalLibConfig = libConfigs.LIBCONFIG_516; + CONFIG517: ModalLibConfig = libConfigs.LIBCONFIG_517; + CONFIG518: ModalLibConfig = libConfigs.LIBCONFIG_518; + CONFIG519: ModalLibConfig = libConfigs.LIBCONFIG_519; + CONFIG520: ModalLibConfig = libConfigs.LIBCONFIG_520; + CONFIG521: ModalLibConfig = libConfigs.LIBCONFIG_521; + CONFIG522: ModalLibConfig = libConfigs.LIBCONFIG_522; + CONFIG523: ModalLibConfig = libConfigs.LIBCONFIG_523; + CONFIG524: ModalLibConfig = libConfigs.LIBCONFIG_524; + CONFIG525: ModalLibConfig = libConfigs.LIBCONFIG_525; + // Examples C + CONFIG600: ModalLibConfig = libConfigs.LIBCONFIG_600; + CONFIG601: ModalLibConfig = libConfigs.LIBCONFIG_601; + CONFIG602: ModalLibConfig = libConfigs.LIBCONFIG_602; + CONFIG603: ModalLibConfig = libConfigs.LIBCONFIG_603; + CONFIG604: ModalLibConfig = libConfigs.LIBCONFIG_604; + CONFIG605: ModalLibConfig = libConfigs.LIBCONFIG_605; + CONFIG606: ModalLibConfig = libConfigs.LIBCONFIG_606; + CONFIG607: ModalLibConfig = libConfigs.LIBCONFIG_607; + CONFIG608: ModalLibConfig = libConfigs.LIBCONFIG_608; + CONFIG609: ModalLibConfig = libConfigs.LIBCONFIG_609; + CONFIG610: ModalLibConfig = libConfigs.LIBCONFIG_610; + CONFIG611: ModalLibConfig = libConfigs.LIBCONFIG_611; + CONFIG612: ModalLibConfig = libConfigs.LIBCONFIG_612; + CONFIG613: ModalLibConfig = libConfigs.LIBCONFIG_613; + // Examples D + CONFIG701: ModalLibConfig = libConfigs.LIBCONFIG_701; + CONFIG702: ModalLibConfig = libConfigs.LIBCONFIG_702; + CONFIG703: ModalLibConfig = libConfigs.LIBCONFIG_703; + // Examples E + CONFIG800: ModalLibConfig = libConfigs.LIBCONFIG_800; + CONFIG801: ModalLibConfig = libConfigs.LIBCONFIG_801; + CONFIG802: ModalLibConfig = libConfigs.LIBCONFIG_802; + // Example F + CONFIG900: ModalLibConfig = libConfigs.LIBCONFIG_900; + + images: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: '../assets/images/gallery/img2.jpg', + description: 'Description 2' + }), + new Image( + 2, + { + img: '../assets/images/gallery/img3.jpg', + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new Image(3, { + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new Image(4, { img: '../assets/images/gallery/img5.jpg' }, { img: '../assets/images/gallery/thumbs/img5.jpg' }) + ]; + + emptyImagesArray: Image[] = []; + + imagesRectNoTitles: Image[] = [ + new Image( + 0, + { img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', title: '' } + ), + new Image( + 1, + { img: '../assets/images/gallery/pexels-photo-47223.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg', title: '' } + ), + new Image( + 2, + { img: '../assets/images/gallery/pexels-photo-52062.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', title: '' } + ), + new Image( + 3, + { img: '../assets/images/gallery/pexels-photo-66943.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', title: '' } + ), + new Image( + 4, + { img: '../assets/images/gallery/pexels-photo-93750.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg', title: '' } + ), + new Image( + 5, + { img: '../assets/images/gallery/pexels-photo-94420.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg', title: '' } + ), + new Image( + 6, + { img: '../assets/images/gallery/pexels-photo-96947.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg', title: '' } + ) + ]; + + fallbackImages: Image[] = [ + new Image(0, { + // this file is not available so the browser returns an error + img: '../assets/images/gallery/UNEXISTING_IMG1.jpg', + // because the img above doesn't exists, the library will use this file + fallbackImg: '../assets/images/gallery/fallback1.jpg' + }), + new Image(1, { + img: '../assets/images/gallery/UNEXISTING_IMG2.jpg', + fallbackImg: '../assets/images/gallery/fallback2.jpg' + }), + new Image( + 2, + { + img: '../assets/images/gallery/UNEXISTING_IMG3.jpg', + fallbackImg: '../assets/images/gallery/fallback3.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG3.png', + fallbackImg: '../assets/images/gallery/fallback3.jpg' + } + ), + new Image(3, { + img: '../assets/images/gallery/UNEXISTING_IMG4.jpg', + fallbackImg: '../assets/images/gallery/fallback4.jpg' + }), + new Image( + 4, + { + img: '../assets/images/gallery/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback5.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback5.jpg' + } + ) + ]; + + // array of images (obviously with different id) where paths are the same. + // to prevent caching issues I have to append '?index'. + sameImages: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg?1', + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: '../assets/images/gallery/img1.jpg?2', + extUrl: 'http://www.google.com' + }), + new Image(2, { + img: '../assets/images/gallery/img1.jpg?3', + extUrl: 'http://www.google.com' + }) + ]; + + // example of a png converted into base64 using https://www.base64-image.de/ or other similar websites + base64String = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABN0lEQV' + + 'R4nO3SQQ2AQBDAwAVlaMEhCkAV' + + 'b2RcQmcU9NEZAAAAAOD/tvN675k5VoewxLOvLmAtA8QZIM4AcQaIM0CcAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4gwQZ4A4A8QZIM4AcQaIM0C' + + 'cAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4gwQZ4A4A8QZIM4AcQaIM0CcAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4g' + + 'wQZ4A4A8QZIM4AcQaIM0CcAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4gwQZ4A4A8QZIM4AcQaIM0CcAeIMEGeAOAPEGQAAAAAA4Pc+8asEoPPGq' + + 'xUAAAAASUVORK5CYII'; + + base64RedString = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAY1BMVEX/AAD/////WVn/+vr/qan/Nzf/ERH/2tr/s7P/KSn/' + + '7+//vr7/0ND/W1v/6+v/m5v/4+P/U1P/HR3/o6P/rq7/g4P/k5P/t7f/dXX/SEj/zMz/ZWX/h4f/bm7/amr/np7/yMhDG/2oAAAC8ElEQVR4nO3dC3KqQBCF4WkHERHFRyKIL/' + + 'a/ymDuVYMMFipTbbfnW8H5S4lQVGUMaWe4B3iHQvlQKB8K5UOhfCiUD4XyoVA+FJ7Myijd5dvBO9nmuzQqZ68X2mI9NO9suC7s84VxNuAO6GSQxU8VJvuQe3pn4T55uLDYcK9+' + + '0KZ4qDB574vPbej+HF2Fcc499km563p0FAbcQ18QdCi0B+6VLzk0fjtuC0dj7o0vGo/uF064B/agvFcYca/rRdReeOTe1pNjW6HkP6J1gbtQwzV4NnEVJtyrepU0C2M599ldhH' + + 'GjcMq9qWfT28KUe1Hv0nrhnHuPB/Na4YJ7jgeLv4UZ9xovsmuhXXKP8WJpL4Ur7i2erC6Fun4Kr8Jz4Rf3Em++/hdKf+htN/5XqOuGtC75LfzmnuHR96nQ6v2SVl9TWxVq/pKevq' + + 'aG1twjvFpXhTLeLz1rQMZyb/DMmhH3BM9GRudjxVVmtN51n62M1DdpXeVG2rveR22MxLe9jxgazfdsJ2Oj9en3THsfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + + 'AAAAAAAAAAAAAAgHba/+98+AFnI+g/30L/GSX6z5nRf1aQ/vOe9J/Zpf/cNf1n533A+Yf6z7DUfw6p/rNkVX9Nkw850/kDzuXWf7Y6ab37Xl0K7ZJ7ixdLeykknQ8YGV0LacG9xo' + + 'MF/S2cc8/xYF4rpJR7T+9SqhfSlHtRz6Z0Wxjr+lEM40ahstvThJqFNOFe1aMJuQop4N7Vm4DchXTkXtaTI7UVUsS9rRcRtRequBZLuldII+mPw+MR3S8ke+De+JKDvQ1qFMr+kx' + + 'o0cxyFFEt945bHjhpXYXV/I/HN8DBxtrgLiQpp74Y3RUtJW2H1Oe7l3IuHe/fnd7+wuh4zGe+lBpnr+utSWLHF+r0vyeG6aPw+PFT4a1ZG6S7fDt7JNt+lUTnrsL5LoWwolA+F8q' + + 'FQPhTKh0L5UCgfCuVDoXw/lnQz7dm7GjoAAAAASUVORK5CYII='; + base64GreenString = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAgMAAADQNkYNAAAADFBMVEUAAAAy/ysy/ysy/ysyTcibAAAAA3RSTlMA2r/af0d' + + 'WAAAAQUlEQVRo3u3YMREAMAzEsJAMyZJsMXy3XORdBFySJK3qxFXH1Y1DEARBEARBEARBEARBEARBkNmk436mvSRJ0o4eOKL2P81eyn8AAAAASUVORK5CYII='; + + base64Image: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.base64String); + base64RedImage: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.base64RedString); + base64GreenImage: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.base64GreenString); + + imagesBase64: Image[] = [ + new Image(0, { + img: this.base64Image, + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: this.base64GreenImage, + description: 'Description 2' + }), + new Image( + 2, + { + img: this.base64RedImage, + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + img: this.base64RedImage, + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ) + ]; + + imagesCustomDownloadFileName: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg', + downloadFileName: 'first-img.jpg' + }), + new Image(1, { + img: this.base64Image, + downloadFileName: 'second-img-base64.jpg' + }) + ]; + + imagesHtmlDescriptions: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: '../assets/images/gallery/img2.jpg', + description: '
  1. This is
  2. the description
  3. number
  4. 2
' + }), + new Image( + 2, + { + img: '../assets/images/gallery/img3.jpg', + description: '
  • Description
  • 3
', + extUrl: 'http://www.google.com' + }, + { + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new Image(3, { + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new Image(4, { img: '../assets/images/gallery/img5.jpg' }, { img: '../assets/images/gallery/thumbs/img5.jpg' }) + ]; + + imagesRect: Image[] = [ + new Image( + 0, + { + img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1' + }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg' } + ), + new Image(1, { img: '../assets/images/gallery/pexels-photo-47223.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg' }), + new Image( + 2, + { + img: '../assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3' + }, + { + img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '../assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4' + }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg' } + ), + new Image(4, { img: '../assets/images/gallery/pexels-photo-93750.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg' }), + new Image( + 5, + { + img: '../assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6' + }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg' } + ), + new Image(6, { img: '../assets/images/gallery/pexels-photo-96947.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg' }) + ]; + + imagesMixedSizes: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/pexels-photo-135230.png', + description: 'Description 1' + }), + new Image(1, { + img: '../assets/images/gallery/pexels-photo-547115.jpeg' + }), + new Image(2, { + img: '../assets/images/gallery/pexels-photo-556664.jpeg', + description: 'Description 3' + }), + new Image(3, { + img: '../assets/images/gallery/pexels-photo-787594.jpeg', + description: 'Description 4' + }), + new Image(4, { + img: '../assets/images/gallery/pexels-photo-803105.jpeg' + }) + ]; + + // example of images with small previews (they are different files) to show + // loading spinners + imagesForLoadingSpinner: Image[] = [ + new Image( + 0, + { + img: '../assets/images/loading-spinner-samples/pexels-photo-74506.jpg' + }, + { img: '../assets/images/loading-spinner-samples/pexels-photo-74506-thumb.jpg' } + ), + new Image( + 1, + { + img: '../assets/images/loading-spinner-samples/pexels-photo-106006.jpg' + }, + { img: '../assets/images/loading-spinner-samples/pexels-photo-106006-thumb.jpg' } + ), + new Image( + 2, + { + img: '../assets/images/loading-spinner-samples/pexels-photo-464336.jpg' + }, + { img: '../assets/images/loading-spinner-samples/pexels-photo-464336-thumb.jpg' } + ), + new Image( + 3, + { + img: '../assets/images/loading-spinner-samples/pexels-photo.jpg' + }, + { img: '../assets/images/loading-spinner-samples/pexels-photo-thumb.jpg' } + ), + new Image( + 4, + { + img: '../assets/images/loading-spinner-samples/traffic-highway-lights-night-56891.jpg' + }, + { img: '../assets/images/loading-spinner-samples/traffic-highway-lights-night-56891-thumb.jpg' } + ) + ]; + + // array with a single image inside (the first one) + singleImage: Image[] = [this.images[0]]; + + imagesInfiniteAutoAdd: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg?1', + extUrl: 'http://www.google.com' + }) + ]; + + private count = 0; + + // subscriptions to receive events from the gallery + // REMEMBER TO call unsubscribe(); in ngOnDestroy (see below) + private closeSubscription: Subscription | undefined; + private showSubscription: Subscription | undefined; + private firstImageSubscription: Subscription | undefined; + private lastImageSubscription: Subscription | undefined; + private hasDataSubscription: Subscription | undefined; + private buttonBeforeHookSubscription: Subscription | undefined; + private buttonAfterHookSubscription: Subscription | undefined; + + constructor(private modalGalleryService: ModalGalleryService, private sanitizer: DomSanitizer) {} + + // this variable is used only for example of auto navigation + // tslint:disable-next-line:no-any + private timeout: any; + + openModalWithAutoClose(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + + this.showSubscription = dialogRef.show$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - show$: ', event); + const galleryId: number = event.galleryId; + console.log(`onShowAutoCloseExample with id=${galleryId} action: ` + Action[event.action]); + console.log('onShowAutoCloseExample result:' + event.result); + console.log('Starting timeout of 3 seconds to close modal gallery automatically'); + // clear previous timeout + clearTimeout(this.timeout); + this.timeout = setTimeout(() => { + console.log('setTimeout end - closing gallery with id=' + galleryId); + this.modalGalleryService.close(galleryId, false); + }, 3000); + }); + } + + addRandomImage(): void { + // add to images array + const imageToCopy: Image = this.images[Math.floor(Math.random() * this.images.length)]; + const newImage: Image = new Image(this.images.length - 1 + 1, imageToCopy.modal, imageToCopy.plain); + this.images = [...this.images, newImage]; + // add also to imagesRect + const imageRectToCopy: Image = this.imagesRect[Math.floor(Math.random() * this.imagesRect.length)]; + const newImageRect: Image = new Image(this.imagesRect.length - 1 + 1, imageRectToCopy.modal, imageRectToCopy.plain); + this.imagesRect = [...this.imagesRect, newImageRect]; + // add also to imagesMixedSizes + const imageMixToCopy: Image = this.imagesMixedSizes[Math.floor(Math.random() * this.imagesMixedSizes.length)]; + const newImageMix: Image = new Image(this.imagesMixedSizes.length - 1 + 1, imageMixToCopy.modal, imageMixToCopy.plain); + this.imagesMixedSizes = [...this.imagesMixedSizes, newImageMix]; + } + + openModal(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + if(imagesArrayToUse.length === 0) { + console.error('Cannot open modal-gallery because images array cannot be empty'); + return; + } + if(imageIndex > imagesArrayToUse.length - 1) { + console.error('Cannot open modal-gallery because imageIndex must be valid'); + return; + } + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + } + + openModalWithOutputs(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.closeSubscription = dialogRef.close$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - close$: ', event); + }); + this.showSubscription = dialogRef.show$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - show$: ', event); + }); + this.firstImageSubscription = dialogRef.firstImage$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - firstImage$: ', event); + }); + this.lastImageSubscription = dialogRef.lastImage$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - lastImage$: ', event); + }); + this.hasDataSubscription = dialogRef.hasData$.subscribe((event: ImageModalEvent) => { + // angular-modal-gallery will emit this event if it will load successfully input images + console.log('OUTPUT - hasData$: ', event); + }); + this.buttonBeforeHookSubscription = dialogRef.buttonBeforeHook$.subscribe((event: ButtonEvent) => { + console.log('OUTPUT - buttonBeforeHook$: ', event); + if (!event || !event.button) { + return; + } + // Invoked after a click on a button, but before that the related + // action is applied. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + if (event.button.type === ButtonType.DELETE) { + // remove the current image and reassign all other to the array of images + console.log('delete in app with images count ' + this.images.length); + this.images = this.images.filter((val: Image) => event.image && val.id !== event.image.id); + } + }); + this.buttonAfterHookSubscription = dialogRef.buttonAfterHook$.subscribe((event: ButtonEvent) => { + if (!event || !event.button) { + return; + } + // Invoked after both a click on a button and its related action. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + }); + } + + openModalWithDeleteButton(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: [...imagesArrayToUse], + currentImage: Object.assign({}, imageToShow), + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.buttonBeforeHookSubscription = dialogRef.buttonBeforeHook$.subscribe((event: ButtonEvent) => { + console.log('OUTPUT - buttonBeforeHook$:', event); + if (!event || !event.button) { + return; + } + // Invoked after a click on a button, but before that the related + // action is applied. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + }); + this.buttonAfterHookSubscription = dialogRef.buttonAfterHook$.subscribe((event: ButtonEvent) => { + console.log('OUTPUT - buttonAfterHook$:', event); + if (!event || !event.button) { + return; + } + if (event.button.type === ButtonType.DELETE) { + // remove the current image and reassign all other to the array of images + this.images = this.images.filter((val: Image) => event.image && val.id !== event.image.id); + this.modalGalleryService.updateModalImages(this.images); + } + // Invoked after both a click on a button and its related action. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + }); + } + + openModalWithAddButton(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.buttonBeforeHookSubscription = dialogRef.buttonBeforeHook$.subscribe((event: ButtonEvent) => { + if (!event || !event.button) { + return; + } + // Invoked after a click on a button, but before that the related + // action is applied. + + if (event.button.type === ButtonType.CUSTOM) { + console.log('adding a new random image at the end'); + this.addRandomImage(); + setTimeout(() => { + this.modalGalleryService.updateModalImages(this.images); + }, 0); + } + }); + this.buttonAfterHookSubscription = dialogRef.buttonAfterHook$.subscribe((event: ButtonEvent) => { + console.log('OUTPUT - buttonAfterHook$:', event); + if (!event || !event.button) { + return; + } + // Invoked after both a click on a button and its related action. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + }); + } + + openModalWithAutoAdd(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.showSubscription = dialogRef.show$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - show$: ', event); + if (this.count !== 0) { + return; + } + const interval = setInterval(() => { + const imageToCopy: Image = this.images[Math.floor(Math.random() * this.images.length)]; + const newImage: Image = new Image(this.imagesInfiniteAutoAdd.length - 1 + 1, imageToCopy.modal, imageToCopy.plain); + newImage.modal.img += `?${this.imagesInfiniteAutoAdd.length + 1}`; + this.imagesInfiniteAutoAdd = [...this.imagesInfiniteAutoAdd, newImage]; + this.modalGalleryService.updateModalImages(this.imagesInfiniteAutoAdd); + this.count++; + if (this.count === 4) { + clearInterval(interval); + } + }, 2000); + }); + } + + openModalWithAutoUpdate(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.showSubscription = dialogRef.show$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - show$: ', event); + if (this.count !== 0) { + return; + } + const indexToRefresh = 1; + const image: Image = new Image(1, { + img: '../assets/images/gallery/img5.jpg', + description: 'Description 2 updated with imag5.jpg' + }); + + console.log('updating image at index ' + indexToRefresh + ', after 4 seconds'); + + // create the new array of images with the updated image inside + const newImages: Image[] = [...this.images]; + newImages[indexToRefresh] = image; + + setTimeout(() => { + this.modalGalleryService.updateModalImages(newImages); + console.log('image updated successfully!'); + }, 4000); + }); + } + + autoPlayButton(config: ModalLibConfig): boolean { + this.isPlaying = !this.isPlaying; + if (config && config.slideConfig && config.slideConfig.playConfig) { + config.slideConfig.playConfig.autoPlay = this.isPlaying; + } + return this.isPlaying; + } + + trackById(index: number, item: Image): number { + return item.id; + } + + openModalWithPreviewsTemplate(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + if(imagesArrayToUse.length === 0) { + console.error('Cannot open modal-gallery because images array cannot be empty'); + return; + } + if(imageIndex > imagesArrayToUse.length - 1) { + console.error('Cannot open modal-gallery because imageIndex must be valid'); + return; + } + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig, + previewsTemplate: this.previewsTemplate, + } as ModalGalleryConfig) as ModalGalleryRef; + } + + ngOnDestroy(): void { + // release resources to prevent memory leaks and unexpected behaviours + if (this.closeSubscription) { + this.closeSubscription.unsubscribe(); + } + if (this.showSubscription) { + this.showSubscription.unsubscribe(); + } + if (this.firstImageSubscription) { + this.firstImageSubscription.unsubscribe(); + } + if (this.lastImageSubscription) { + this.lastImageSubscription.unsubscribe(); + } + if (this.hasDataSubscription) { + this.hasDataSubscription.unsubscribe(); + } + if (this.buttonBeforeHookSubscription) { + this.buttonBeforeHookSubscription.unsubscribe(); + } + if (this.buttonAfterHookSubscription) { + this.buttonAfterHookSubscription.unsubscribe(); + } + } +} diff --git a/examples/angular-cli-19/src/app/modal-gallery/modal-gallery.html b/examples/angular-cli-19/src/app/modal-gallery/modal-gallery.html new file mode 100644 index 00000000..2a264c8b --- /dev/null +++ b/examples/angular-cli-19/src/app/modal-gallery/modal-gallery.html @@ -0,0 +1,325 @@ +

Modal Gallery

+
+ +

If you want, you can add a random image to every example + +

+
+

Index to open:   

+
+
+

WARNING: remember to use always different ids across your application!!!

+
+
+
+

Minimal examples

+
+

A1 - (id=400) - Minimal demo - all defaults (images array)

+ +
+
+

A1bis - (id=401) - Minimal demo - all defaults with rect images (imagesRect array)

+ +
+
+

A1tris - (id=402) - Minimal demo - all defaults with images of different sizes (imagesMixedSizes array)

+ +
+
+

A2 - (id=403) - Minimal demo - listen for events

+

I added 'openModalWithOutputs()' public method to listen for events

+ +
+
+

A3 - (id=405) - Minimal demo - single image (singleImage array)

+ +
+
+

A4 - (id=406) - Minimal demo - single image with infinite sliding enabled (to fix issue #156)

+ +
+
+

A5 - (id=407) - Minimal demo - two images with infinite sliding enabled (to fix issue #156)

+ +
+
+

A6 - (id=408) - Minimal demo - three image with infinite sliding enabled (to fix issue #156)

+ +
+
+

A7 - (id=409) - Minimal demo - use fallback images when it's not possible to load normal images (to fix issue #194)

+ +
+
+
+
+

Simple examples

+
+

B1 - (id=500) - Simple demo - only current image and buttons (previews and dots are hidden)

+ +
+
+

B2 - (id=501) - Simple demo - only current image (buttons, previews and dots are hidden)

+ +
+
+

B3 - (id=502) - Simple demo - only current image (side previews, buttons, previews and dots are hidden)

+ +
+
+

B3bis - (id=503) - Simple demo - custom preview size

+ +
+
+

B4 - (id=504) - Simple demo - disable closeOutside

+ +
+
+

B5 - (id=505) - Simple demo - no downloadable at all

+ +
+
+

B6 - (id=506) - Simple demo - no download button (only with keyboard)

+ +
+
+

B7 - (id=507) - Simple demo - download with both button and keyboard

+ +
+
+

B8 - (id=508) - Simple demo - infinite sliding but NO side previews

+ +
+
+

B9 - (id=509) - Simple demo - infinite sliding and side previews

+ +
+
+

B10 - (id=510) - Simple demo - disable loading spinner

+ +
+
+

B11 - (id=511) - Simple demo - loading spinner of type Standard

+ +
+
+

B12 - (id=512) - Simple demo - loading spinner of type Circular

+ +
+
+

B13 - (id=513) - Simple demo - loading spinner of type Bars

+ +
+
+

B14 - (id=514) - Simple demo - loading spinner of type Dots

+ +
+
+

B15 - (id=515) - Simple demo - loading spinner of type Cube Flipping

+ +
+
+

B16 - (id=516) - Simple demo - loading spinner of type Circles

+ +
+
+

B17 - (id=517) - Simple demo - loading spinner of type Explosing Squares

+ +
+ +
+

B18 - (id=518) - Simple demo - buttons config DEFAULT strategy (only close)

+ +
+
+

B19 - (id=519) - Simple demo - buttons config SIMPLE strategy (close and download)

+ +
+
+

B20 - (id=520) - Simple demo - buttons config ADVANCED strategy (close, download and exturl in the current + tab)

+ +
+
+

B21 - (id=521) - Simple demo - buttons config FULL strategy (all buttons)

+

I added also 'openModalWithDeleteButton()' public method to support delete button

+ +
+
+

B22 - (id=522) - Simple demo - buttons config CUSTOM strategy with exturl in ANOTHER TAB ('_blank')

+ +
+
+

B23 - (id=523) - Simple demo - buttons config CUSTOM but with all default buttons already included in the library

+

I added also 'openModalWithDeleteButton()' public method to support delete button

+ +
+
+

B24 - (id=524) - Simple demo - buttons config CUSTOM strategy with Font Awesome 5

+

I added also 'openModalWithAddButton()' public method to support delete button

+
+ +
+
+

B25 - (id=525) - Previews visible on mobile screen

+

Added PreviewConfig.mobileVisible configuration param

+
+ +
+
+
+
+

Advanced examples

+
+

C1 - (id=600) - Advanced demo - custom keyboard ('up'/'down' arrows and 'q' to close)

+ +
+
+

C2 - (id=601) - Advanced demo - custom description always visible

+ +
+
+

C3 - (id=602) - Advanced demo - custom description hide if empty

+ +
+
+

C4 - (id=603) - Advanced demo - custom description always hidden

+ +
+
+

C5 - (id=604) - Advanced demo - custom FULL description always visible

+ +
+
+

C6 - (id=605) - Advanced demo - custom HTML description always visible

+ +
+
+

C7 - (id=606) - Advanced demo - custom description style (always visible)

+ +
+ +
+

C8 - (id=607) - Advanced demo - preview custom configuration with 1 image (clickable)

+ +
+ +
+

C9 - (id=608) - Advanced demo - preview custom configuration with 5 images (clickable)

+ +
+ +
+

C10 - (id=609) - Advanced demo - preview custom configuration without arrows (clickable)

+ +
+
+

C11 - (id=610) - Advanced demo - preview custom configuration not clickable

+ +
+
+

C12 - (id=611) - Advanced demo - preview custom configuration with custom size

+ +
+ +
+

C13 - (id=612) - Advanced demo - accessibility config

+ +
+ +
+

C14 - (id=613) - Advanced demo - disable clicks on current image in modal-image

+ +
+ +
+

C15 - (id=614) - Advanced demo - after 3 seconds it closes modal gallery automatically with galleryService close method

+

Attention: please check the console to understand what it's happening!

+

Timer will clear and restart every time you show another image!

+ +
+ +
+
+
+

Other examples

+
+

D1 - (id=700) - Other demo - base64 images

+ +
+ +
+

D2 - (id=701) - Other demo - custom file name, used when downloaded

+ +
+ +
+

D3 - (id=702) - Other demo - invert touchscreen swipe direction

+ +
+ +
+

D4 - (id=703) - Other demo - infinite sliding and automatic add of images when the gallery is visible

+ +
+ +
+

D5 - (id=704) - Other demo - automatic update of the second image (index=1) via gallery service (open the second image and wait some seconds to see the result)

+ +
+ +
+

D6 - (id=705) - Other demo - remove title attribute on images

+ +
+ +
+

D7 - (id=706) - Other demo - modal gallery with an empty images array

+ +
+ +
+
+
+

AutoPlay examples

+
+

E1 - (id=800) - AutoPlay demo - with interval=5000 and pauseOnHover enabled

+ +
+
+

E2 - (id=801) - AutoPlay demo - with interval=5000, pauseOnHover disabled and infinite is enabled

+ +
+
+

E3 - (id=802) - AutoPlay demo - with interval=1000 and pauseOnHover disabled

+

+ +
+ + +
+
+
+

Experimental examples*

+

* these will be either improved or removed in next versions

+
+

F1 - (id=900) - Experimental demo - infinite sliding with only one image to see if side arrows are hidden

+ +
+
+

F2 - (id=901) - Experimental demo - an array of Images with the same source file (different classes/ids and paths with appended '?imageIndex' to prevent caching issues)

+ +
+
+

F3 - (id=902) - Experimental demo - 'previews' rendering customization (via Angular templates)

+ +
+
{{preview?.modal?.description ?? ' '}}
+
+ +
+
+
+ +
+ diff --git a/examples/angular-cli-19/src/app/modal-gallery/modal-gallery.scss b/examples/angular-cli-19/src/app/modal-gallery/modal-gallery.scss new file mode 100644 index 00000000..994466cd --- /dev/null +++ b/examples/angular-cli-19/src/app/modal-gallery/modal-gallery.scss @@ -0,0 +1,177 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +:host { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + margin-left: 20px; + margin-right: 20px; +} + +$text-color: #fff; +$background: rgba(0, 0, 0, .7); + +button { + background-color: #0060b7; + color: white; + height: 25px; + width: auto; + border: 0; + border-radius: 5px; + cursor: pointer; + + &:hover { + background-color: #0086ff; + } +} + +.my-app-custom-plain-container-row { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + .my-app-custom-image-row { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-column { + align-items: center; + display: flex; + flex-direction: column; + justify-content: flex-start; + + .my-app-custom-image-column { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-with-desc { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + figure { + margin: 0; + position: relative; + + img { + max-width: 100%; + height: auto; + cursor: pointer; + } + + figcaption { + background: rgba(0, 0, 0, .5); + color: #fff; + font-size: 85%; + padding: 5px; + position: absolute; + bottom: 3px; + left: 0; + right: 0; + } + } + + .description { + font-weight: bold; + text-align: center; + } + + .my-app-custom-image-with-desc { + height: auto; + margin-right: 2px; + width: 200px; + align-self: start; + } +} + +.more { + background: $background; + cursor: pointer; + color: $text-color; + padding-top: 4px; + height: 46px; + position: absolute; + text-align: center; + width: 50px; +} + + +.transcluded { + color: white; + font-weight: 600; + font-size: 24px; + text-align: center; + position: absolute; + top: 50%; + width: 100%; + pointer-events: none; +} + +.title { + margin-top: 40px; +} + +.preview-block { + margin-right: 10px; +} +.preview-description { + color: #fff; + margin-bottom: 3px; +} +.preview-description, +.preview-default { + text-align: center; +} diff --git a/examples/angular-cli-19/src/app/navbar/navbar.component.ts b/examples/angular-cli-19/src/app/navbar/navbar.component.ts new file mode 100644 index 00000000..7708d11a --- /dev/null +++ b/examples/angular-cli-19/src/app/navbar/navbar.component.ts @@ -0,0 +1,63 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { Component } from '@angular/core'; +import { Router } from '@angular/router'; +import { BreakpointObserver } from '@angular/cdk/layout'; + +@Component({ + selector: 'ks-navbar', + templateUrl: 'navbar.html', + styleUrls: ['navbar.scss'], + standalone: false +}) +export class NavbarComponent { + navbarHeight = '56px'; + // path: string = PATH + '/assets/amg.svg'; + + collapsed = false; + + constructor(private router: Router, breakpointObserver: BreakpointObserver) { + breakpointObserver.observe(['(min-width: 990px)']).subscribe(result => { + if (result.matches) { + console.log('min width 990px'); + this.collapsed = false; + } + }); + } + + isNavItemActive(location: string): string { + return this.router.url.includes(location) ? 'active' : ''; + } + + onNavigateTo(path: string): void { + this.collapsed = false; + this.router.navigate([path]); + } + + onToggle(): void { + this.collapsed = !this.collapsed; + this.navbarHeight = this.collapsed ? '56px' : '150px'; + } +} diff --git a/examples/angular-cli-19/src/app/navbar/navbar.html b/examples/angular-cli-19/src/app/navbar/navbar.html new file mode 100644 index 00000000..f95de0c4 --- /dev/null +++ b/examples/angular-cli-19/src/app/navbar/navbar.html @@ -0,0 +1,68 @@ + + + + + diff --git a/examples/angular-cli-19/src/app/navbar/navbar.scss b/examples/angular-cli-19/src/app/navbar/navbar.scss new file mode 100644 index 00000000..f8580359 --- /dev/null +++ b/examples/angular-cli-19/src/app/navbar/navbar.scss @@ -0,0 +1,233 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +nav { + padding-top: 8px; + padding-bottom: 8px; + padding-left: 16px; + padding-right: 16px; +} + +ul { + margin-top: 0; + margin-bottom: 0; + padding-left: 0; +} + +nav.nav-expanded { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + background-color: #343A40; + padding-top: 8px; + padding-left: 16px; + padding-bottom: 8px; + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 10; + + > .navbar-hamburger { + display: none; + background-color: #343A40; + border-color: rgba(255, 255, 255, .1); + + @media screen and (max-width: 990px) { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + cursor: pointer; + padding-top: 4px; + padding-bottom: 4px; + padding-left: 12px; + padding-right: 12px; + } + } + + > .navbar-wrapper { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + + @media screen and (max-width: 990px) { + display: none; + } + + > .navbar-brand { + font-size: 16px; + color: #ffffff; + font-weight: 400; + margin-left: 8px; + margin-right: 8px; + cursor: pointer; + + > img { + border-radius: 3px + } + + &:hover { + color: #bdbdbd; + } + } + + > .navbar-nav { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + list-style: none; + + > .nav-item { + cursor: pointer; + color: #e2e2e2; + + > a.nav-link { + color: #b9b9b9; + font-size: 14px; + font-weight: 400; + margin-left: 8px; + margin-right: 8px; + + &:hover { + color: #E2E2E2; + } + } + } + } + } + + > #githubButtons { + margin-right: 30px; + @media only screen and (max-width: 1059px) { + display: none; + } + + > .github-badge { + margin-left: 8px; + } + } +} + + +// cexpanded on mobile devices after pressing the hamburger button +nav.nav-collapsed { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + flex-wrap: wrap; + background-color: #343A40; + padding-top: 8px; + padding-left: 16px; + padding-bottom: 8px; + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 10; + + > .navbar-hamburger { + display: none; + background-color: #343A40; + border-color: rgba(255, 255, 255, .1); + + @media screen and (max-width: 990px) { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + cursor: pointer; + padding-top: 4px; + padding-bottom: 4px; + padding-left: 12px; + padding-right: 12px; + } + } + + > .navbar-wrapper { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + margin-top: 8px; + width: 100%; + + > .navbar-brand { + font-size: 16px; + color: #ffffff; + font-weight: 400; + margin-left: 8px; + margin-right: 8px; + margin-top: 8px; + margin-bottom: 8px; + cursor: pointer; + width: 100%; + + > img { + border-radius: 3px + } + + &:hover { + color: #bdbdbd; + } + } + + > .navbar-nav { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + width: 100%; + list-style: none; + + > .nav-item { + cursor: pointer; + color: #e2e2e2; + width: 100%; + margin-top: 8px; + margin-bottom: 8px; + + > a.nav-link { + color: #b9b9b9; + font-size: 14px; + font-weight: 400; + margin-left: 8px; + margin-right: 8px; + + &:hover { + color: #E2E2E2; + } + } + } + } + } +} + + + diff --git a/examples/angular-cli-19/src/app/plain-gallery/plain-gallery.component.ts b/examples/angular-cli-19/src/app/plain-gallery/plain-gallery.component.ts new file mode 100644 index 00000000..d6136df5 --- /dev/null +++ b/examples/angular-cli-19/src/app/plain-gallery/plain-gallery.component.ts @@ -0,0 +1,297 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; + +import { + GridLayout, + Image, + LineLayout, + PlainGalleryConfig, + PlainGalleryStrategy, + ModalGalleryService, + ModalGalleryRef, + PlainLibConfig +} from '@ks89/angular-modal-gallery'; + +@Component({ + selector: 'ks-plain-gallery-page', + templateUrl: './plain-gallery.html', + styleUrls: ['./plain-gallery.scss'], + standalone: false +}) +export class PlainGalleryExampleComponent { + plainGalleryRow: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout({ width: '80px', height: '80px' }, { length: 2, wrap: true }, 'flex-start') + }; + plainGalleryRowSpaceAround: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout({ width: '50px', height: '50px' }, { length: 2, wrap: true }, 'space-around') + }; + plainGalleryRowATags: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout({ width: '95px', height: '63px' }, { length: 4, wrap: true }, 'flex-start'), + // when advanced is defined, additionalBackground: '50% 50%/cover' will be used by default. + // I added this here, to be more explicit. + advanced: { aTags: true, additionalBackground: '50% 50%/cover' } + }; + + plainGalleryColumn: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.COLUMN, + layout: new LineLayout({ width: '50px', height: '50px' }, { length: 3, wrap: true }, 'flex-start') + }; + + plainGalleryGrid: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.GRID, + layout: new GridLayout({ width: '80px', height: '80px' }, { length: 3, wrap: true }) + }; + + images: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: '../assets/images/gallery/img2.jpg', + description: 'Description 2' + }), + new Image( + 2, + { + img: '../assets/images/gallery/img3.jpg', + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new Image(3, { + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new Image(4, { img: '../assets/images/gallery/img5.jpg' }, { img: '../assets/images/gallery/thumbs/img5.jpg' }) + ]; + + emptyImagesArray: Image[] = []; + + fallbackImages: Image[] = [ + new Image(0, { + // this file is not available so the browser returns an error + img: '../assets/images/gallery/UNEXISTING_IMG1.jpg', + // because the img above doesn't exists, the library will use this file + fallbackImg: '../assets/images/gallery/fallback1.jpg' + }), + new Image(1, { + img: '../assets/images/gallery/UNEXISTING_IMG2.jpg', + fallbackImg: '../assets/images/gallery/fallback2.jpg' + }), + new Image( + 2, + { + img: '../assets/images/gallery/UNEXISTING_IMG3.jpg', + fallbackImg: '../assets/images/gallery/fallback3.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG3.png', + fallbackImg: '../assets/images/gallery/fallback3.jpg' + } + ), + new Image(3, { + img: '../assets/images/gallery/UNEXISTING_IMG4.jpg', + fallbackImg: '../assets/images/gallery/fallback4.jpg' + }), + new Image( + 4, + { + img: '../assets/images/gallery/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback5.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback5.jpg' + } + ) + ]; + + imagesRect: Image[] = [ + new Image( + 0, + { + img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1' + }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg' } + ), + new Image(1, { img: '../assets/images/gallery/pexels-photo-47223.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg' }), + new Image( + 2, + { + img: '../assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3' + }, + { + img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '../assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4' + }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg' } + ), + new Image(4, { img: '../assets/images/gallery/pexels-photo-93750.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg' }), + new Image( + 5, + { + img: '../assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6' + }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg' } + ), + new Image(6, { img: '../assets/images/gallery/pexels-photo-96947.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg' }) + ]; + + imagesRectNoTitles: Image[] = [ + new Image( + 0, + { img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', title: '' } + ), + new Image( + 1, + { img: '../assets/images/gallery/pexels-photo-47223.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg', title: '' } + ), + new Image( + 2, + { img: '../assets/images/gallery/pexels-photo-52062.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', title: '' } + ), + new Image( + 3, + { img: '../assets/images/gallery/pexels-photo-66943.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', title: '' } + ), + new Image( + 4, + { img: '../assets/images/gallery/pexels-photo-93750.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg', title: '' } + ), + new Image( + 5, + { img: '../assets/images/gallery/pexels-photo-94420.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg', title: '' } + ), + new Image( + 6, + { img: '../assets/images/gallery/pexels-photo-96947.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg', title: '' } + ) + ]; + + libConfigPlainGalleryRow: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryRow + }; + libConfigPlainGalleryRowSpaceAround: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryRowSpaceAround + }; + libConfigPlainGalleryRowATags: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryRowATags + }; + libConfigPlainGalleryColumn: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryColumn + }; + libConfigPlainGalleryGrid: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryGrid + }; + + constructor(private modalGalleryService: ModalGalleryService, private sanitizer: DomSanitizer) {} + + openImageModalRow(id: number, image: Image): void { + console.log('Opening modal gallery from custom plain gallery row, with image: ', image); + const index: number = this.getCurrentIndexCustomLayout(image, this.images); + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: this.images, + currentImage: this.images[index] + }) as ModalGalleryRef; + } + + openImageModalColumn(id: number, image: Image): void { + console.log('Opening modal gallery from custom plain gallery column, with image: ', image); + const index: number = this.getCurrentIndexCustomLayout(image, this.images); + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: this.images, + currentImage: this.images[index] + }) as ModalGalleryRef; + } + + openImageModalRowDescription(id: number, image: Image): void { + console.log('Opening modal gallery from custom plain gallery row and description, with image: ', image); + const index: number = this.getCurrentIndexCustomLayout(image, this.imagesRect); + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: this.imagesRect, + currentImage: this.imagesRect[index] + }) as ModalGalleryRef; + } + + addRandomImage(): void { + // add to images array + const imageToCopy: Image = this.images[Math.floor(Math.random() * this.images.length)]; + const newImage: Image = new Image(this.images.length - 1 + 1, imageToCopy.modal, imageToCopy.plain); + this.images = [...this.images, newImage]; + // add also to imagesRect + const imageRectToCopy: Image = this.imagesRect[Math.floor(Math.random() * this.imagesRect.length)]; + const newImageRect: Image = new Image(this.imagesRect.length - 1 + 1, imageRectToCopy.modal, imageRectToCopy.plain); + this.imagesRect = [...this.imagesRect, newImageRect]; + } + + onShow(id: number, index: number, images: Image[] = this.images): void { + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images, + currentImage: images[index] + }) as ModalGalleryRef; + } + + trackById(index: number, item: Image): number { + return item.id; + } + + private getCurrentIndexCustomLayout(image: Image, images: Image[]): number { + return image ? images.indexOf(image) : -1; + } +} diff --git a/examples/angular-cli-19/src/app/plain-gallery/plain-gallery.html b/examples/angular-cli-19/src/app/plain-gallery/plain-gallery.html new file mode 100644 index 00000000..73f06879 --- /dev/null +++ b/examples/angular-cli-19/src/app/plain-gallery/plain-gallery.html @@ -0,0 +1,152 @@ +

Plain Gallery

+
+ +

If you want, you can add a random image to every example + +

+
+
+

Layout examples

+
+

P1 - (id=200) - row plain gallery layout (limit 2) and custom size

+
+ +
+
+
+

P2 - (id=201) - row plain gallery layout space around (limit 2)

+
+ +
+
+
+

P3 - (id=202) - row plain gallery layout with a tags and custom rectangular sizes (limit 4)

+
+ +
+
+
+

P4 - (id=203) - column plain gallery layout (limit 3)

+
+ +
+
+
+

P5 - (id=204) - grid plain gallery layout and custom size

+
+ +
+
+
+

P6 - (id=205) - full custom plain gallery (row) with image pointer

+
+
+ + + +
+
+
+
+

P7 - (id=206) - full custom plain gallery (column) with image pointer

+
+
+ + + +
+
+
+
+

P8 - (id=207) - full custom plain gallery (row) with descriptions

+
+
+ +
+ +
{{img.modal.description ? img.modal.description : 'No description available'}} +
+
+
+
+
+
+
+

P9 - (id=208) - row plain gallery layout with fallback images when it's not possible to load normal images (to fix issue #194)

+
+ +
+
+
+

P10 - (id=209) - row plain gallery layout with a tags and custom rectangular sizes (limit 4) + fallback images when it's not possible to load normal images (to fix issue #194)

+
+ +
+
+
+

P11 - (id=210) - row plain gallery layout (limit 2) and custom size + remove title attribute on images

+
+ +
+
+
+

P12 - (id=211) - row plain gallery layout with an empty images array

+
+ +
+
+
diff --git a/examples/angular-cli-19/src/app/plain-gallery/plain-gallery.scss b/examples/angular-cli-19/src/app/plain-gallery/plain-gallery.scss new file mode 100644 index 00000000..b498df8d --- /dev/null +++ b/examples/angular-cli-19/src/app/plain-gallery/plain-gallery.scss @@ -0,0 +1,169 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +:host { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + margin-left: 20px; + margin-right: 20px; +} + +section { + width: 100%; +} + +$text-color: #fff; +$background: rgba(0, 0, 0, .7); + +button { + background-color: #0060b7; + color: white; + height: 25px; + width: auto; + border: 0; + border-radius: 5px; + cursor: pointer; + + &:hover { + background-color: #0086ff; + } +} + +.my-app-custom-plain-container-row { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + .my-app-custom-image-row { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-column { + align-items: center; + display: flex; + flex-direction: column; + justify-content: flex-start; + + .my-app-custom-image-column { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-with-desc { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + figure { + margin: 0; + position: relative; + + img { + max-width: 100%; + height: auto; + cursor: pointer; + } + + figcaption { + background: rgba(0, 0, 0, .5); + color: #fff; + font-size: 85%; + padding: 5px; + position: absolute; + bottom: 3px; + left: 0; + right: 0; + } + } + + .description { + font-weight: bold; + text-align: center; + } + + .my-app-custom-image-with-desc { + height: auto; + margin-right: 2px; + width: 200px; + align-self: start; + } +} + +.more { + background: $background; + cursor: pointer; + color: $text-color; + padding-top: 4px; + height: 46px; + position: absolute; + text-align: center; + width: 50px; +} + + +.transcluded { + color: white; + font-weight: 600; + font-size: 24px; + text-align: center; + position: absolute; + top: 50%; + width: 100%; + pointer-events: none; +} + +.title { + margin-top: 40px; +} diff --git a/examples/angular-cli-19/src/assets/images/gallery/fallback-carousel1.jpg b/examples/angular-cli-19/src/assets/images/gallery/fallback-carousel1.jpg new file mode 100644 index 00000000..5d49263f Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/fallback-carousel1.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/fallback-carousel2.jpg b/examples/angular-cli-19/src/assets/images/gallery/fallback-carousel2.jpg new file mode 100644 index 00000000..2c2ce26a Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/fallback-carousel2.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/fallback-carousel3.jpg b/examples/angular-cli-19/src/assets/images/gallery/fallback-carousel3.jpg new file mode 100644 index 00000000..a4ea6b40 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/fallback-carousel3.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/fallback-carousel4.jpg b/examples/angular-cli-19/src/assets/images/gallery/fallback-carousel4.jpg new file mode 100644 index 00000000..0d59507d Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/fallback-carousel4.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/fallback-carousel5.jpg b/examples/angular-cli-19/src/assets/images/gallery/fallback-carousel5.jpg new file mode 100644 index 00000000..5511feb8 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/fallback-carousel5.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/fallback1.jpg b/examples/angular-cli-19/src/assets/images/gallery/fallback1.jpg new file mode 100644 index 00000000..0827c782 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/fallback1.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/fallback2.jpg b/examples/angular-cli-19/src/assets/images/gallery/fallback2.jpg new file mode 100644 index 00000000..6562c517 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/fallback2.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/fallback3.jpg b/examples/angular-cli-19/src/assets/images/gallery/fallback3.jpg new file mode 100644 index 00000000..3a3d63f4 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/fallback3.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/fallback4.jpg b/examples/angular-cli-19/src/assets/images/gallery/fallback4.jpg new file mode 100644 index 00000000..0dfe8551 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/fallback4.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/fallback5.jpg b/examples/angular-cli-19/src/assets/images/gallery/fallback5.jpg new file mode 100644 index 00000000..38da58e4 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/fallback5.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/img1.jpg b/examples/angular-cli-19/src/assets/images/gallery/img1.jpg new file mode 100644 index 00000000..7d358899 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/img1.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/img2.jpg b/examples/angular-cli-19/src/assets/images/gallery/img2.jpg new file mode 100644 index 00000000..4c101c12 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/img2.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/img2.png b/examples/angular-cli-19/src/assets/images/gallery/img2.png new file mode 100644 index 00000000..295cb1f4 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/img2.png differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/img3.jpg b/examples/angular-cli-19/src/assets/images/gallery/img3.jpg new file mode 100644 index 00000000..c6b1c22d Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/img3.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/img4.jpg b/examples/angular-cli-19/src/assets/images/gallery/img4.jpg new file mode 100644 index 00000000..403482ae Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/img4.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/img5.jpg b/examples/angular-cli-19/src/assets/images/gallery/img5.jpg new file mode 100644 index 00000000..bf97ab6c Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/img5.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/milan-pegasus-gallery-statue-1024w.jpg b/examples/angular-cli-19/src/assets/images/gallery/milan-pegasus-gallery-statue-1024w.jpg new file mode 100644 index 00000000..c0a922d1 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/milan-pegasus-gallery-statue-1024w.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/milan-pegasus-gallery-statue-480w.jpg b/examples/angular-cli-19/src/assets/images/gallery/milan-pegasus-gallery-statue-480w.jpg new file mode 100644 index 00000000..ac54d7d7 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/milan-pegasus-gallery-statue-480w.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/milan-pegasus-gallery-statue-768w.jpg b/examples/angular-cli-19/src/assets/images/gallery/milan-pegasus-gallery-statue-768w.jpg new file mode 100644 index 00000000..dba50163 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/milan-pegasus-gallery-statue-768w.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/milan-pegasus-gallery-statue.jpg b/examples/angular-cli-19/src/assets/images/gallery/milan-pegasus-gallery-statue.jpg new file mode 100644 index 00000000..f2c02760 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/milan-pegasus-gallery-statue.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-135230-1024w.png b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-135230-1024w.png new file mode 100644 index 00000000..a543d4db Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-135230-1024w.png differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-135230-480w.png b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-135230-480w.png new file mode 100644 index 00000000..dc29041e Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-135230-480w.png differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-135230-768w.png b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-135230-768w.png new file mode 100644 index 00000000..b04917ed Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-135230-768w.png differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-135230.png b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-135230.png new file mode 100644 index 00000000..8aa887fd Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-135230.png differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-47223-1024w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-47223-1024w.jpeg new file mode 100644 index 00000000..f7931c21 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-47223-1024w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-47223-480w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-47223-480w.jpeg new file mode 100644 index 00000000..14897ecf Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-47223-480w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-47223-768w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-47223-768w.jpeg new file mode 100644 index 00000000..73f72c9a Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-47223-768w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-47223.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-47223.jpeg new file mode 100644 index 00000000..46ea1f75 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-47223.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-52062-1024w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-52062-1024w.jpeg new file mode 100644 index 00000000..a7052fd3 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-52062-1024w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-52062-480w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-52062-480w.jpeg new file mode 100644 index 00000000..1ac7ce8c Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-52062-480w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-52062-768w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-52062-768w.jpeg new file mode 100644 index 00000000..e1f3256c Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-52062-768w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-52062.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-52062.jpeg new file mode 100644 index 00000000..0c9502e4 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-52062.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-547115-1024w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-547115-1024w.jpeg new file mode 100644 index 00000000..592a1516 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-547115-1024w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-547115-480w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-547115-480w.jpeg new file mode 100644 index 00000000..15c404dd Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-547115-480w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-547115-768w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-547115-768w.jpeg new file mode 100644 index 00000000..68fa15da Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-547115-768w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-547115.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-547115.jpeg new file mode 100644 index 00000000..4056b197 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-547115.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-556664-1024w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-556664-1024w.jpeg new file mode 100644 index 00000000..b56cf006 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-556664-1024w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-556664-480w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-556664-480w.jpeg new file mode 100644 index 00000000..f7990e34 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-556664-480w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-556664-768w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-556664-768w.jpeg new file mode 100644 index 00000000..cbb74582 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-556664-768w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-556664.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-556664.jpeg new file mode 100644 index 00000000..33383d36 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-556664.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-66943-1024w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-66943-1024w.jpeg new file mode 100644 index 00000000..18988bf3 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-66943-1024w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-66943-480w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-66943-480w.jpeg new file mode 100644 index 00000000..c40829b9 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-66943-480w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-66943-768w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-66943-768w.jpeg new file mode 100644 index 00000000..953ef6f3 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-66943-768w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-66943.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-66943.jpeg new file mode 100644 index 00000000..8dd20157 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-66943.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-787594-1024w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-787594-1024w.jpeg new file mode 100644 index 00000000..52113fef Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-787594-1024w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-787594-480w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-787594-480w.jpeg new file mode 100644 index 00000000..3b97fb45 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-787594-480w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-787594-768w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-787594-768w.jpeg new file mode 100644 index 00000000..b08cc133 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-787594-768w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-787594.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-787594.jpeg new file mode 100644 index 00000000..e2986131 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-787594.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-803105-1024w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-803105-1024w.jpeg new file mode 100644 index 00000000..99bb60cd Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-803105-1024w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-803105-480w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-803105-480w.jpeg new file mode 100644 index 00000000..815624dc Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-803105-480w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-803105-768w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-803105-768w.jpeg new file mode 100644 index 00000000..1118cde8 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-803105-768w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-803105.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-803105.jpeg new file mode 100644 index 00000000..8b7c44a4 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-803105.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-93750-1024w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-93750-1024w.jpeg new file mode 100644 index 00000000..bf1e8eaf Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-93750-1024w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-93750-480w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-93750-480w.jpeg new file mode 100644 index 00000000..08020dbe Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-93750-480w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-93750-768w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-93750-768w.jpeg new file mode 100644 index 00000000..8fe37d40 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-93750-768w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-93750.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-93750.jpeg new file mode 100644 index 00000000..ab537b02 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-93750.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-94420-1024w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-94420-1024w.jpeg new file mode 100644 index 00000000..c8a13148 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-94420-1024w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-94420-480w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-94420-480w.jpeg new file mode 100644 index 00000000..acc790e7 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-94420-480w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-94420-768w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-94420-768w.jpeg new file mode 100644 index 00000000..11fbaad9 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-94420-768w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-94420.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-94420.jpeg new file mode 100644 index 00000000..d3ebb012 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-94420.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-96947-1024w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-96947-1024w.jpeg new file mode 100644 index 00000000..3e4a701f Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-96947-1024w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-96947-480w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-96947-480w.jpeg new file mode 100644 index 00000000..0248070f Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-96947-480w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-96947-768w.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-96947-768w.jpeg new file mode 100644 index 00000000..c74f523e Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-96947-768w.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-96947.jpeg b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-96947.jpeg new file mode 100644 index 00000000..c6965748 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/pexels-photo-96947.jpeg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback-carousel1.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback-carousel1.jpg new file mode 100644 index 00000000..5ce2a4ed Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback-carousel1.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback-carousel2.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback-carousel2.jpg new file mode 100644 index 00000000..6417a30b Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback-carousel2.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback-carousel3.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback-carousel3.jpg new file mode 100644 index 00000000..a0939a7a Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback-carousel3.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback-carousel4.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback-carousel4.jpg new file mode 100644 index 00000000..5be118b7 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback-carousel4.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback-carousel5.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback-carousel5.jpg new file mode 100644 index 00000000..c61eb0ee Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback-carousel5.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback1.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback1.jpg new file mode 100644 index 00000000..2afb5530 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback1.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback2.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback2.jpg new file mode 100644 index 00000000..140e9718 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback2.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback3.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback3.jpg new file mode 100644 index 00000000..11115387 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback3.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback4.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback4.jpg new file mode 100644 index 00000000..9737793b Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback4.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback5.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback5.jpg new file mode 100644 index 00000000..88915773 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/fallback5.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/img1.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/img1.jpg new file mode 100644 index 00000000..68e10d14 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/img1.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/img2.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/img2.jpg new file mode 100644 index 00000000..3b69746a Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/img2.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/img3.png b/examples/angular-cli-19/src/assets/images/gallery/thumbs/img3.png new file mode 100644 index 00000000..3f0bf060 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/img3.png differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/img4.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/img4.jpg new file mode 100644 index 00000000..d08ebe7f Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/img4.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/img5.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/img5.jpg new file mode 100644 index 00000000..b932ee9f Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/img5.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg new file mode 100644 index 00000000..6881e08c Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg new file mode 100644 index 00000000..be93d546 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg new file mode 100644 index 00000000..eb99fe42 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg new file mode 100644 index 00000000..e33dc4be Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg new file mode 100644 index 00000000..feae47af Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg new file mode 100644 index 00000000..075cdd51 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg b/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg new file mode 100644 index 00000000..ab777557 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-106006-thumb.jpg b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-106006-thumb.jpg new file mode 100644 index 00000000..e80e1a53 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-106006-thumb.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-106006.jpg b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-106006.jpg new file mode 100644 index 00000000..6baa8325 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-106006.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-464336-thumb.jpg b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-464336-thumb.jpg new file mode 100644 index 00000000..7bd64447 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-464336-thumb.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-464336.jpg b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-464336.jpg new file mode 100644 index 00000000..c7253d57 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-464336.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-74506-thumb.jpg b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-74506-thumb.jpg new file mode 100644 index 00000000..24028aa0 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-74506-thumb.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-74506.jpg b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-74506.jpg new file mode 100644 index 00000000..c4973505 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-74506.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-thumb.jpg b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-thumb.jpg new file mode 100644 index 00000000..34615206 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo-thumb.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo.jpg b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo.jpg new file mode 100644 index 00000000..3ceffcbe Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/pexels-photo.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891-thumb.jpg b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891-thumb.jpg new file mode 100644 index 00000000..8cfda5fa Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891-thumb.jpg differ diff --git a/examples/angular-cli-19/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891.jpg b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891.jpg new file mode 100644 index 00000000..9457c1c6 Binary files /dev/null and b/examples/angular-cli-19/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891.jpg differ diff --git a/examples/angular-cli-19/src/assets/menu.svg b/examples/angular-cli-19/src/assets/menu.svg new file mode 100644 index 00000000..65fc9003 --- /dev/null +++ b/examples/angular-cli-19/src/assets/menu.svg @@ -0,0 +1,3 @@ + + + diff --git a/examples/angular-cli-19/src/favicon.png b/examples/angular-cli-19/src/favicon.png new file mode 100644 index 00000000..4e279875 Binary files /dev/null and b/examples/angular-cli-19/src/favicon.png differ diff --git a/examples/angular-cli-19/src/index.html b/examples/angular-cli-19/src/index.html new file mode 100644 index 00000000..dc3730df --- /dev/null +++ b/examples/angular-cli-19/src/index.html @@ -0,0 +1,18 @@ + + + + + @ks89/angular-modal-gallery demo + + + + + + + + + + + diff --git a/examples/angular-cli-19/src/main.ts b/examples/angular-cli-19/src/main.ts new file mode 100644 index 00000000..1d335a67 --- /dev/null +++ b/examples/angular-cli-19/src/main.ts @@ -0,0 +1,8 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule, { + ngZoneEventCoalescing: true +}) + .catch(err => console.error(err)); diff --git a/examples/angular-cli-19/src/styles.scss b/examples/angular-cli-19/src/styles.scss new file mode 100644 index 00000000..47d84e5a --- /dev/null +++ b/examples/angular-cli-19/src/styles.scss @@ -0,0 +1,61 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// You can add global styles to this file, and also import other style files + +// ***************************************************************** +// *********** required by @ks89/angular-modal-gallery ************* +// ***************************************************************** +// ATTENTION: You have to install @angular/cdk to be able to use @ks89/angular-modal-gallery properly +@import "@angular/cdk/overlay-prebuilt.css"; + +.ks-modal-gallery-backdrop { + background: #000 !important;; + opacity: 0.85 !important;; +} + +.ks-modal-gallery-panel { + z-index: 90000 !important; +} +// ***************************************************************** +// ***************************************************************** +// ***************************************************************** + +body { + font-family: "Montserrat", sans-serif; + margin: 0; + padding: 0; +} + +// Not required by angular-modal-gallery. Used only in this demo +.red-text { + color: red; +} + +.title { + text-align: center; + color: red; +} + +.center-text { + text-align: center; +} diff --git a/examples/angular-cli-19/tsconfig.app.json b/examples/angular-cli-19/tsconfig.app.json new file mode 100644 index 00000000..3775b37e --- /dev/null +++ b/examples/angular-cli-19/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/examples/angular-cli-19/tsconfig.json b/examples/angular-cli-19/tsconfig.json new file mode 100644 index 00000000..3110e6e1 --- /dev/null +++ b/examples/angular-cli-19/tsconfig.json @@ -0,0 +1,32 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "compileOnSave": false, + "compilerOptions": { + "outDir": "./dist/out-tsc", + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "isolatedModules": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "moduleResolution": "bundler", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "useDefineForClassFields": false, // to inject sanitizer without errors + "lib": [ + "ES2022", + "dom" + ] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/examples/angular-cli-19/tsconfig.spec.json b/examples/angular-cli-19/tsconfig.spec.json new file mode 100644 index 00000000..5fb748d9 --- /dev/null +++ b/examples/angular-cli-19/tsconfig.spec.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/examples/angular-cli-material/.editorconfig b/examples/angular-cli-material/.editorconfig new file mode 100644 index 00000000..59d9a3a3 --- /dev/null +++ b/examples/angular-cli-material/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/examples/angular-cli-material/.gitignore b/examples/angular-cli-material/.gitignore new file mode 100644 index 00000000..105c00f2 --- /dev/null +++ b/examples/angular-cli-material/.gitignore @@ -0,0 +1,46 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist +/tmp +/out-tsc +# Only exists if Bazel was run +/bazel-out + +# dependencies +/node_modules + +# profiling files +chrome-profiler-events*.json + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# misc +/.angular/cache +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System Files +.DS_Store +Thumbs.db diff --git a/examples/angular-cli-material/.vscode/extensions.json b/examples/angular-cli-material/.vscode/extensions.json new file mode 100644 index 00000000..77b37457 --- /dev/null +++ b/examples/angular-cli-material/.vscode/extensions.json @@ -0,0 +1,4 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 + "recommendations": ["angular.ng-template"] +} diff --git a/examples/angular-cli-material/.vscode/launch.json b/examples/angular-cli-material/.vscode/launch.json new file mode 100644 index 00000000..925af837 --- /dev/null +++ b/examples/angular-cli-material/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "ng serve", + "type": "chrome", + "request": "launch", + "preLaunchTask": "npm: start", + "url": "http://localhost:4200/" + }, + { + "name": "ng test", + "type": "chrome", + "request": "launch", + "preLaunchTask": "npm: test", + "url": "http://localhost:9876/debug.html" + } + ] +} diff --git a/examples/angular-cli-material/.vscode/tasks.json b/examples/angular-cli-material/.vscode/tasks.json new file mode 100644 index 00000000..a298b5bd --- /dev/null +++ b/examples/angular-cli-material/.vscode/tasks.json @@ -0,0 +1,42 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "start", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "(.*?)" + }, + "endsPattern": { + "regexp": "bundle generation complete" + } + } + } + }, + { + "type": "npm", + "script": "test", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "(.*?)" + }, + "endsPattern": { + "regexp": "bundle generation complete" + } + } + } + } + ] +} diff --git a/examples/angular-cli-material/angular.json b/examples/angular-cli-material/angular.json new file mode 100644 index 00000000..388eccf2 --- /dev/null +++ b/examples/angular-cli-material/angular.json @@ -0,0 +1,108 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "angular-cli": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "ks", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:application", + "options": { + "outputPath": "dist/angular-cli", + "index": "src/index.html", + "browser": "src/main.ts", + "polyfills": [ + "zone.js" + ], + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "src/favicon.png", + "src/assets", + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", + "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": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-cli:build:production" + }, + "development": { + "buildTarget": "angular-cli:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n" + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "polyfills": [ + "zone.js", + "zone.js/testing" + ], + "tsConfig": "tsconfig.spec.json", + "inlineStyleLanguage": "scss", + "assets": [ + "src/favicon.png", + "src/assets", + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", + "src/styles.scss" + ], + "scripts": [] + } + } + } + } + } +} diff --git a/examples/angular-cli-material/package-lock.json b/examples/angular-cli-material/package-lock.json new file mode 100644 index 00000000..b47a3139 --- /dev/null +++ b/examples/angular-cli-material/package-lock.json @@ -0,0 +1,13736 @@ +{ + "name": "angular-cli", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "angular-cli", + "version": "0.0.0", + "dependencies": { + "@angular/animations": "^19.0.5", + "@angular/cdk": "^19.0.4", + "@angular/common": "^19.0.5", + "@angular/compiler": "^19.0.5", + "@angular/core": "^19.0.5", + "@angular/forms": "^19.0.5", + "@angular/material": "^19.0.4", + "@angular/platform-browser": "^19.0.5", + "@angular/platform-browser-dynamic": "^19.0.5", + "@angular/router": "^19.0.5", + "@fortawesome/fontawesome-svg-core": "^6.7.2", + "@fortawesome/free-solid-svg-icons": "^6.7.2", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^19.0.6", + "@angular/cli": "~19.0.6", + "@angular/compiler-cli": "^19.0.5", + "@types/jasmine": "~5.1.0", + "@types/node": "^20.10.0", + "jasmine-core": "~5.1.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.6.3" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@angular-devkit/architect": { + "version": "0.1900.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1900.6.tgz", + "integrity": "sha512-w11bAXQnNWBawTJfQPjvaTRrzrqsOUm9tK9WNvaia/xjiRFpmO0CfmKtn3axNSEJM8jb/czaNQrgTwG+TGc/8g==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "19.0.6", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/architect/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/architect/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/architect/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/architect/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/build-angular": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-19.0.6.tgz", + "integrity": "sha512-dWTAsE6BSI8z0xglQdYBdqTBwg1Q+RWE3OrmlGs+520Dcoq/F0Z41Y1F3MiuHuQPdDAIQr88iB0APkIRW4clMg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1900.6", + "@angular-devkit/build-webpack": "0.1900.6", + "@angular-devkit/core": "19.0.6", + "@angular/build": "19.0.6", + "@babel/core": "7.26.0", + "@babel/generator": "7.26.2", + "@babel/helper-annotate-as-pure": "7.25.9", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-transform-async-generator-functions": "7.25.9", + "@babel/plugin-transform-async-to-generator": "7.25.9", + "@babel/plugin-transform-runtime": "7.25.9", + "@babel/preset-env": "7.26.0", + "@babel/runtime": "7.26.0", + "@discoveryjs/json-ext": "0.6.3", + "@ngtools/webpack": "19.0.6", + "@vitejs/plugin-basic-ssl": "1.1.0", + "ansi-colors": "4.1.3", + "autoprefixer": "10.4.20", + "babel-loader": "9.2.1", + "browserslist": "^4.21.5", + "copy-webpack-plugin": "12.0.2", + "css-loader": "7.1.2", + "esbuild-wasm": "0.24.0", + "fast-glob": "3.3.2", + "http-proxy-middleware": "3.0.3", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", + "karma-source-map-support": "1.4.0", + "less": "4.2.0", + "less-loader": "12.2.0", + "license-webpack-plugin": "4.0.2", + "loader-utils": "3.3.1", + "mini-css-extract-plugin": "2.9.2", + "open": "10.1.0", + "ora": "5.4.1", + "picomatch": "4.0.2", + "piscina": "4.7.0", + "postcss": "8.4.49", + "postcss-loader": "8.1.1", + "resolve-url-loader": "5.0.0", + "rxjs": "7.8.1", + "sass": "1.80.7", + "sass-loader": "16.0.3", + "semver": "7.6.3", + "source-map-loader": "5.0.0", + "source-map-support": "0.5.21", + "terser": "5.36.0", + "tree-kill": "1.2.2", + "tslib": "2.8.1", + "webpack": "5.96.1", + "webpack-dev-middleware": "7.4.2", + "webpack-dev-server": "5.1.0", + "webpack-merge": "6.0.1", + "webpack-subresource-integrity": "5.1.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "esbuild": "0.24.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^19.0.0", + "@angular/localize": "^19.0.0", + "@angular/platform-server": "^19.0.0", + "@angular/service-worker": "^19.0.0", + "@angular/ssr": "^19.0.6", + "@web/test-runner": "^0.19.0", + "browser-sync": "^3.0.2", + "jest": "^29.5.0", + "jest-environment-jsdom": "^29.5.0", + "karma": "^6.3.0", + "ng-packagr": "^19.0.0", + "protractor": "^7.0.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=5.5 <5.7" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "@web/test-runner": { + "optional": true + }, + "browser-sync": { + "optional": true + }, + "jest": { + "optional": true + }, + "jest-environment-jsdom": { + "optional": true + }, + "karma": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "protractor": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.1900.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1900.6.tgz", + "integrity": "sha512-WehtVrbBow4fc7hsaUKb+BZ6MDE5lO98/tgv7GR5PkRdGKnyLA0pW1AfPLJJQDgcaKjneramMhDFNc1eGSX0mQ==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1900.6", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "webpack": "^5.30.0", + "webpack-dev-server": "^5.0.2" + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.0.6.tgz", + "integrity": "sha512-R9hlHfAh1HKoIWgnYJlOEKhUezhTNl0fpUmHxG2252JSY5FLRxmYArTtJYYmbNdBbsBLNg3UHyM/GBPvJSA3NQ==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "19.0.6", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.12", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/animations": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-19.0.5.tgz", + "integrity": "sha512-HCOF2CrhUvjoZWusd4nh32VOxpUrg6bV+3Z8Q36Ix3aZdni8v0qoP2rl5wGbotaPtYg5RtyDH60Z2AOPKqlrZg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.0.5" + } + }, + "node_modules/@angular/build": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-19.0.6.tgz", + "integrity": "sha512-KEVNLgTZUF2dfpOYQn+yR2HONHUTxq/2rFVhiK9qAvrm/m+uKJNEXx7hGtbRyoqenZff4ScJq+7feITUldfX8g==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1900.6", + "@babel/core": "7.26.0", + "@babel/helper-annotate-as-pure": "7.25.9", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-syntax-import-attributes": "7.26.0", + "@inquirer/confirm": "5.0.2", + "@vitejs/plugin-basic-ssl": "1.1.0", + "beasties": "0.1.0", + "browserslist": "^4.23.0", + "esbuild": "0.24.0", + "fast-glob": "3.3.2", + "https-proxy-agent": "7.0.5", + "istanbul-lib-instrument": "6.0.3", + "listr2": "8.2.5", + "magic-string": "0.30.12", + "mrmime": "2.0.0", + "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "4.0.2", + "piscina": "4.7.0", + "rollup": "4.26.0", + "sass": "1.80.7", + "semver": "7.6.3", + "vite": "5.4.11", + "watchpack": "2.4.2" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "lmdb": "3.1.5" + }, + "peerDependencies": { + "@angular/compiler": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "@angular/localize": "^19.0.0", + "@angular/platform-server": "^19.0.0", + "@angular/service-worker": "^19.0.0", + "@angular/ssr": "^19.0.6", + "less": "^4.2.0", + "postcss": "^8.4.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=5.5 <5.7" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "less": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular/build/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular/build/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular/cdk": { + "version": "19.0.4", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-19.0.4.tgz", + "integrity": "sha512-P8V1n6AFFjBUJG3YRgw8DiiNDWPZVrwQ42wbwgZxd4s2TQAuNFg3YY8h/DSMVxt2sXpavrshZsoLtP9yLKZjHA==", + "dependencies": { + "tslib": "^2.3.0" + }, + "optionalDependencies": { + "parse5": "^7.1.2" + }, + "peerDependencies": { + "@angular/common": "^19.0.0 || ^20.0.0", + "@angular/core": "^19.0.0 || ^20.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/cli": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-19.0.6.tgz", + "integrity": "sha512-ZEHhgRRVIdn10dbsAjB8TE9Co32hfuL9/im5Jcfa1yrn6KJefmigz6KN8Xu7FXMH5FkdqfQ11QpLBxJSPb9aww==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1900.6", + "@angular-devkit/core": "19.0.6", + "@angular-devkit/schematics": "19.0.6", + "@inquirer/prompts": "7.1.0", + "@listr2/prompt-adapter-inquirer": "2.0.18", + "@schematics/angular": "19.0.6", + "@yarnpkg/lockfile": "1.1.0", + "ini": "5.0.0", + "jsonc-parser": "3.3.1", + "listr2": "8.2.5", + "npm-package-arg": "12.0.0", + "npm-pick-manifest": "10.0.0", + "pacote": "20.0.0", + "resolve": "1.22.8", + "semver": "7.6.3", + "symbol-observable": "4.0.0", + "yargs": "17.7.2" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/cli/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular/cli/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular/cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/cli/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/cli/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular/common": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-19.0.5.tgz", + "integrity": "sha512-fFK+euCj1AjBHBCpj9VnduMSeqoMRhZZHbhPYiND7tucRRJ8vwGU0sYK2KI/Ko+fsrNIXL/0O4F36jVPl09Smg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.0.5", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/compiler": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-19.0.5.tgz", + "integrity": "sha512-S8ku5Ljp0kqX3shfmE9DVo09629jeYJSlBRGbj2Glb92dd+VQZPOz7KxqKRTwmAl7lQIV/+4Lr6G/GVTsoC4vg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.0.5" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + } + } + }, + "node_modules/@angular/compiler-cli": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.0.5.tgz", + "integrity": "sha512-KSzuWCTZlvJsoAenxM9cjTOzNM8mrFxDBInj0KVPz7QU83amGS4rcv1pWO/QGYQcErfskcN84TAdMegaRWWCmA==", + "dev": true, + "dependencies": { + "@babel/core": "7.26.0", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^4.0.0", + "convert-source-map": "^1.5.1", + "reflect-metadata": "^0.2.0", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^17.2.1" + }, + "bin": { + "ng-xi18n": "bundles/src/bin/ng_xi18n.js", + "ngc": "bundles/src/bin/ngc.js", + "ngcc": "bundles/ngcc/index.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/compiler": "19.0.5", + "typescript": ">=5.5 <5.7" + } + }, + "node_modules/@angular/compiler-cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/compiler-cli/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/core": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-19.0.5.tgz", + "integrity": "sha512-Ywc6sPO6G/Y1stfk3y/MallV/h0yzQ0vdOHRWueLrk5kD1DTdbolV4X03Cs3PuVvravgcSVE3nnuuHFuH32emQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.15.0" + } + }, + "node_modules/@angular/forms": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-19.0.5.tgz", + "integrity": "sha512-OhNFkfOoguqCDq07vNBV28FFrmTM8S11Z3Cd6PQZJJF9TgAtpV5KtF7A3eXBCN92W4pmqluomPjfK7YyImzIYQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.0.5", + "@angular/core": "19.0.5", + "@angular/platform-browser": "19.0.5", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/material": { + "version": "19.0.4", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-19.0.4.tgz", + "integrity": "sha512-8WRMbN1+oRXx1ZFLni+BRz60F4FWzJPFORsQ8qAvY3sHWzyjunsYZkpbze3uiZO6bu3hiyQCU6g+k/58Qc6kkw==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/animations": "^19.0.0 || ^20.0.0", + "@angular/cdk": "19.0.4", + "@angular/common": "^19.0.0 || ^20.0.0", + "@angular/core": "^19.0.0 || ^20.0.0", + "@angular/forms": "^19.0.0 || ^20.0.0", + "@angular/platform-browser": "^19.0.0 || ^20.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.0.5.tgz", + "integrity": "sha512-41+Jo5DEil4Ifvv+UE/p1l9YJtYN+xfhx+/C9cahVgvV5D2q+givyK73d0Mnb6XOfe1q+hoV5lZ+XhQYp21//g==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/animations": "19.0.5", + "@angular/common": "19.0.5", + "@angular/core": "19.0.5" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/platform-browser-dynamic": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-19.0.5.tgz", + "integrity": "sha512-KKFdue/uJVxkWdrntRAXkz+ycp4nD3SuGOH5pPf2svCBxieuHuFlWDi+DYVuFSEpC/ICCmlhrtzIAm44A4qzzQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.0.5", + "@angular/compiler": "19.0.5", + "@angular/core": "19.0.5", + "@angular/platform-browser": "19.0.5" + } + }, + "node_modules/@angular/router": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-19.0.5.tgz", + "integrity": "sha512-6tNubVVj/rRyTg+OXjQxACfufvCLHAwDQtv9wqt6q/3OYSnysHTik3ho3FaFPwu7fXJ+6p9Rjzkh2VY9QMk4bw==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.0.5", + "@angular/core": "19.0.5", + "@angular/platform-browser": "19.0.5", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", + "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.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/convert-source-map": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "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==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.26.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz", + "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", + "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", + "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.38.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.26.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", + "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.3", + "@babel/parser": "^7.26.3", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.3", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", + "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.26.3", + "@babel/types": "^7.26.3", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", + "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", + "dev": true, + "engines": { + "node": ">=14.17.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", + "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz", + "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz", + "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz", + "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz", + "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz", + "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz", + "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz", + "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz", + "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz", + "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz", + "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz", + "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz", + "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz", + "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz", + "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz", + "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz", + "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz", + "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz", + "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz", + "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz", + "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz", + "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz", + "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz", + "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.2.tgz", + "integrity": "sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.2.tgz", + "integrity": "sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.2.tgz", + "integrity": "sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.0.4.tgz", + "integrity": "sha512-fYAKCAcGNMdfjL6hZTRUwkIByQ8EIZCXKrIQZH7XjADnN/xvRUhj8UdBbpC4zoUzvChhkSC/zRKaP/tDs3dZpg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.0.2.tgz", + "integrity": "sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/core": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.2.tgz", + "integrity": "sha512-bHd96F3ezHg1mf/J0Rb4CV8ndCN0v28kUlrHqP7+ECm1C/A+paB7Xh2lbMk6x+kweQC+rZOxM/YeKikzxco8bQ==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core/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==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.1.tgz", + "integrity": "sha512-xn9aDaiP6nFa432i68JCaL302FyL6y/6EG97nAtfIPnWZ+mWPgCMLGc4XZ2QQMsZtu9q3Jd5AzBPjXh10aX9kA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.4.tgz", + "integrity": "sha512-GYocr+BPyxKPxQ4UZyNMqZFSGKScSUc0Vk17II3J+0bDcgGsQm0KYQNooN1Q5iBfXsy3x/VWmHGh20QnzsaHwg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.9.tgz", + "integrity": "sha512-BXvGj0ehzrngHTPTDqUoDT3NXL8U0RxUk2zJm2A66RhCEIWdtU1v6GuUqNAgArW4PQ9CinqIWyHdQgdwOj06zQ==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.1.tgz", + "integrity": "sha512-nAXAHQndZcXB+7CyjIW3XuQZZHbQQ0q8LX6miY6bqAWwDzNa9JUioDBYrFmOUNIsuF08o1WT/m2gbBXvBhYVxg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.4.tgz", + "integrity": "sha512-DX7a6IXRPU0j8kr2ovf+QaaDiIf+zEKaZVzCWdLOTk7XigqSXvoh4cul7x68xp54WTQrgSnW7P1WBJDbyY3GhA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.4.tgz", + "integrity": "sha512-wiliQOWdjM8FnBmdIHtQV2Ca3S1+tMBUerhyjkRCv1g+4jSvEweGu9GCcvVEgKDhTBT15nrxvk5/bVrGUqSs1w==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.1.0.tgz", + "integrity": "sha512-5U/XiVRH2pp1X6gpNAjWOglMf38/Ys522ncEHIKT1voRUvSj/DQnR22OVxHnwu5S+rCFaUiPQ57JOtMFQayqYA==", + "dev": true, + "dependencies": { + "@inquirer/checkbox": "^4.0.2", + "@inquirer/confirm": "^5.0.2", + "@inquirer/editor": "^4.1.0", + "@inquirer/expand": "^4.0.2", + "@inquirer/input": "^4.0.2", + "@inquirer/number": "^3.0.2", + "@inquirer/password": "^4.0.2", + "@inquirer/rawlist": "^4.0.2", + "@inquirer/search": "^3.0.2", + "@inquirer/select": "^4.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.0.4.tgz", + "integrity": "sha512-IsVN2EZdNHsmFdKWx9HaXb8T/s3FlR/U1QPt9dwbSyPtjFbMTlW9CRFvnn0bm/QIsrMRD2oMZqrQpSWPQVbXXg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/search": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.4.tgz", + "integrity": "sha512-tSkJk2SDmC2MEdTIjknXWmCnmPr5owTs9/xjfa14ol1Oh95n6xW7SYn5fiPk4/vrJPys0ggSWiISdPze4LTa7A==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/select": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.0.4.tgz", + "integrity": "sha512-ZzYLuLoUzTIW9EJm++jBpRiTshGqS3Q1o5qOEQqgzaBlmdsjQr6pA4TUNkwu6OBYgM2mIRbCz6mUhFDfl/GF+w==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.2.tgz", + "integrity": "sha512-ZhQ4TvhwHZF+lGhQ2O/rsjo80XoZR5/5qhOY3t6FJuX5XBg5Be8YzYTvaUGJnc12AUGI2nr4QSUE4PhKSigx7g==", + "dev": true, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/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==", + "dev": true + }, + "node_modules/@isaacs/cliui/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==", + "dev": true, + "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/@isaacs/cliui/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/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==", + "dev": true, + "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/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "dev": true, + "license": "MIT", + "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.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.1.tgz", + "integrity": "sha512-osjeBqMJ2lb/j/M8NCPjs1ylqWIcTRTycIhVB5pt6LgzgeRSb0YRZ7j9RfA8wIUrsr/medIuhVyonXRZWLyfdw==", + "dev": true, + "dependencies": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.5.0.tgz", + "integrity": "sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true + }, + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.18.tgz", + "integrity": "sha512-0hz44rAcrphyXcA8IS7EJ2SCoaBZD2u5goE8S/e+q/DL+dOGpqpcLidVOFeLG3VgML62SXmfRLAhWt0zL1oW4Q==", + "dev": true, + "dependencies": { + "@inquirer/type": "^1.5.5" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 8" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/@inquirer/type": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", + "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", + "dev": true, + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.1.5.tgz", + "integrity": "sha512-ue5PSOzHMCIYrfvPP/MRS6hsKKLzqqhcdAvJCO8uFlDdj598EhgnacuOTuqA6uBK5rgiZXfDWyb7DVZSiBKxBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.1.5.tgz", + "integrity": "sha512-CGhsb0R5vE6mMNCoSfxHFD8QTvBHM51gs4DBeigTYHWnYv2V5YpJkC4rMo5qAAFifuUcc0+a8a3SIU0c9NrfNw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.1.5.tgz", + "integrity": "sha512-3WeW328DN+xB5PZdhSWmqE+t3+44xWXEbqQ+caWJEZfOFdLp9yklBZEbVqVdqzznkoaXJYxTCp996KD6HmANeg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.1.5.tgz", + "integrity": "sha512-LAjaoOcBHGj6fiYB8ureiqPoph4eygbXu4vcOF+hsxiY74n8ilA7rJMmGUT0K0JOB5lmRQHSmor3mytRjS4qeQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.1.5.tgz", + "integrity": "sha512-k/IklElP70qdCXOQixclSl2GPLFiopynGoKX1FqDd1/H0E3Fo1oPwjY2rEVu+0nS3AOw1sryStdXk8CW3cVIsw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.1.5.tgz", + "integrity": "sha512-KYar6W8nraZfSJspcK7Kp7hdj238X/FNauYbZyrqPBrtsXI1hvI4/KcRcRGP50aQoV7fkKDyJERlrQGMGTZUsA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@napi-rs/nice": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.0.1.tgz", + "integrity": "sha512-zM0mVWSXE0a0h9aKACLwKmD6nHcRiKrPpCfvaKqG1CqDEyjEawId0ocXxVzPMCAm6kkWr2P025msfxXEnt8UGQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/nice-android-arm-eabi": "1.0.1", + "@napi-rs/nice-android-arm64": "1.0.1", + "@napi-rs/nice-darwin-arm64": "1.0.1", + "@napi-rs/nice-darwin-x64": "1.0.1", + "@napi-rs/nice-freebsd-x64": "1.0.1", + "@napi-rs/nice-linux-arm-gnueabihf": "1.0.1", + "@napi-rs/nice-linux-arm64-gnu": "1.0.1", + "@napi-rs/nice-linux-arm64-musl": "1.0.1", + "@napi-rs/nice-linux-ppc64-gnu": "1.0.1", + "@napi-rs/nice-linux-riscv64-gnu": "1.0.1", + "@napi-rs/nice-linux-s390x-gnu": "1.0.1", + "@napi-rs/nice-linux-x64-gnu": "1.0.1", + "@napi-rs/nice-linux-x64-musl": "1.0.1", + "@napi-rs/nice-win32-arm64-msvc": "1.0.1", + "@napi-rs/nice-win32-ia32-msvc": "1.0.1", + "@napi-rs/nice-win32-x64-msvc": "1.0.1" + } + }, + "node_modules/@napi-rs/nice-android-arm-eabi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.1.tgz", + "integrity": "sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-android-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.0.1.tgz", + "integrity": "sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.0.1.tgz", + "integrity": "sha512-91k3HEqUl2fsrz/sKkuEkscj6EAj3/eZNCLqzD2AA0TtVbkQi8nqxZCZDMkfklULmxLkMxuUdKe7RvG/T6s2AA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.1.tgz", + "integrity": "sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-freebsd-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.0.1.tgz", + "integrity": "sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.0.1.tgz", + "integrity": "sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.0.1.tgz", + "integrity": "sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-musl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.0.1.tgz", + "integrity": "sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-ppc64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.0.1.tgz", + "integrity": "sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-riscv64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.0.1.tgz", + "integrity": "sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-s390x-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.0.1.tgz", + "integrity": "sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.0.1.tgz", + "integrity": "sha512-XQAJs7DRN2GpLN6Fb+ZdGFeYZDdGl2Fn3TmFlqEL5JorgWKrQGRUrpGKbgZ25UeZPILuTKJ+OowG2avN8mThBA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-musl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.0.1.tgz", + "integrity": "sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-arm64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.0.1.tgz", + "integrity": "sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-ia32-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.0.1.tgz", + "integrity": "sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-x64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.0.1.tgz", + "integrity": "sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ngtools/webpack": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-19.0.6.tgz", + "integrity": "sha512-eWrIb0tS1CK6+JvFS4GgTD4fN9TtmApKrlaj3pPQXKXKKd42361ec85fuQQXdb4G8eEEq0vyd/bn4NJllh/3vw==", + "dev": true, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^19.0.0", + "typescript": ">=5.5 <5.7", + "webpack": "^5.54.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz", + "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/@npmcli/fs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz", + "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-6.0.1.tgz", + "integrity": "sha512-BBWMMxeQzalmKadyimwb2/VVQyJB01PH0HhVSNLHNBDZN/M/h/02P6f8fxedIiFhpMj11SO9Ep5tKTBE7zL2nw==", + "dev": true, + "dependencies": { + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-3.0.0.tgz", + "integrity": "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q==", + "dev": true, + "dependencies": { + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-6.1.0.tgz", + "integrity": "sha512-t6G+6ZInT4X+tqj2i+wlLIeCKnKOTuz9/VFYDtj+TGTur5q7sp/OYrQA19LdBbWfXDOi0Y4jtedV6xtB8zQ9ug==", + "dev": true, + "dependencies": { + "@npmcli/git": "^6.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "normalize-package-data": "^7.0.0", + "proc-log": "^5.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/package-json/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-8.0.2.tgz", + "integrity": "sha512-/bNJhjc+o6qL+Dwz/bqfTQClkEO5nTQ1ZEcdCkAQjhkZMHIh22LPG7fNh1enJP1NKWDqYiiABnjFCY7E0zHYtQ==", + "dev": true, + "dependencies": { + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-3.0.0.tgz", + "integrity": "sha512-/1uFzjVcfzqrgCeGW7+SZ4hv0qLWmKXVzFahZGJ6QuJBj6Myt9s17+JL86i76NV9YSnJRcGXJYQbAU0rn1YTCQ==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-9.0.2.tgz", + "integrity": "sha512-cJXiUlycdizQwvqE1iaAb4VRUM3RX09/8q46zjvy+ct9GhfZRWd7jXYVc1tn/CfRlGPVkX/u4sstRlepsm7hfw==", + "dev": true, + "dependencies": { + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "node-gyp": "^11.0.0", + "proc-log": "^5.0.0", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.0.tgz", + "integrity": "sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.0", + "@parcel/watcher-darwin-arm64": "2.5.0", + "@parcel/watcher-darwin-x64": "2.5.0", + "@parcel/watcher-freebsd-x64": "2.5.0", + "@parcel/watcher-linux-arm-glibc": "2.5.0", + "@parcel/watcher-linux-arm-musl": "2.5.0", + "@parcel/watcher-linux-arm64-glibc": "2.5.0", + "@parcel/watcher-linux-arm64-musl": "2.5.0", + "@parcel/watcher-linux-x64-glibc": "2.5.0", + "@parcel/watcher-linux-x64-musl": "2.5.0", + "@parcel/watcher-win32-arm64": "2.5.0", + "@parcel/watcher-win32-ia32": "2.5.0", + "@parcel/watcher-win32-x64": "2.5.0" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.0.tgz", + "integrity": "sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.0.tgz", + "integrity": "sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.0.tgz", + "integrity": "sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.0.tgz", + "integrity": "sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.0.tgz", + "integrity": "sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.0.tgz", + "integrity": "sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.0.tgz", + "integrity": "sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.0.tgz", + "integrity": "sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.0.tgz", + "integrity": "sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.0.tgz", + "integrity": "sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.0.tgz", + "integrity": "sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.0.tgz", + "integrity": "sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.0.tgz", + "integrity": "sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@parcel/watcher/node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "optional": true + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.26.0.tgz", + "integrity": "sha512-gJNwtPDGEaOEgejbaseY6xMFu+CPltsc8/T+diUTTbOQLqD+bnrJq9ulH6WD69TqwqWmrfRAtUv30cCFZlbGTQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.26.0.tgz", + "integrity": "sha512-YJa5Gy8mEZgz5JquFruhJODMq3lTHWLm1fOy+HIANquLzfIOzE9RA5ie3JjCdVb9r46qfAQY/l947V0zfGJ0OQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.26.0.tgz", + "integrity": "sha512-ErTASs8YKbqTBoPLp/kA1B1Um5YSom8QAc4rKhg7b9tyyVqDBlQxy7Bf2wW7yIlPGPg2UODDQcbkTlruPzDosw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.26.0.tgz", + "integrity": "sha512-wbgkYDHcdWW+NqP2mnf2NOuEbOLzDblalrOWcPyY6+BRbVhliavon15UploG7PpBRQ2bZJnbmh8o3yLoBvDIHA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.26.0.tgz", + "integrity": "sha512-Y9vpjfp9CDkAG4q/uwuhZk96LP11fBz/bYdyg9oaHYhtGZp7NrbkQrj/66DYMMP2Yo/QPAsVHkV891KyO52fhg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.26.0.tgz", + "integrity": "sha512-A/jvfCZ55EYPsqeaAt/yDAG4q5tt1ZboWMHEvKAH9Zl92DWvMIbnZe/f/eOXze65aJaaKbL+YeM0Hz4kLQvdwg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.26.0.tgz", + "integrity": "sha512-paHF1bMXKDuizaMODm2bBTjRiHxESWiIyIdMugKeLnjuS1TCS54MF5+Y5Dx8Ui/1RBPVRE09i5OUlaLnv8OGnA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.26.0.tgz", + "integrity": "sha512-cwxiHZU1GAs+TMxvgPfUDtVZjdBdTsQwVnNlzRXC5QzIJ6nhfB4I1ahKoe9yPmoaA/Vhf7m9dB1chGPpDRdGXg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.26.0.tgz", + "integrity": "sha512-4daeEUQutGRCW/9zEo8JtdAgtJ1q2g5oHaoQaZbMSKaIWKDQwQ3Yx0/3jJNmpzrsScIPtx/V+1AfibLisb3AMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.26.0.tgz", + "integrity": "sha512-eGkX7zzkNxvvS05ROzJ/cO/AKqNvR/7t1jA3VZDi2vRniLKwAWxUr85fH3NsvtxU5vnUUKFHKh8flIBdlo2b3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.26.0.tgz", + "integrity": "sha512-Odp/lgHbW/mAqw/pU21goo5ruWsytP7/HCC/liOt0zcGG0llYWKrd10k9Fj0pdj3prQ63N5yQLCLiE7HTX+MYw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.26.0.tgz", + "integrity": "sha512-MBR2ZhCTzUgVD0OJdTzNeF4+zsVogIR1U/FsyuFerwcqjZGvg2nYe24SAHp8O5sN8ZkRVbHwlYeHqcSQ8tcYew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.26.0.tgz", + "integrity": "sha512-YYcg8MkbN17fMbRMZuxwmxWqsmQufh3ZJFxFGoHjrE7bv0X+T6l3glcdzd7IKLiwhT+PZOJCblpnNlz1/C3kGQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.26.0.tgz", + "integrity": "sha512-ZuwpfjCwjPkAOxpjAEjabg6LRSfL7cAJb6gSQGZYjGhadlzKKywDkCUnJ+KEfrNY1jH5EEoSIKLCb572jSiglA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.26.0.tgz", + "integrity": "sha512-+HJD2lFS86qkeF8kNu0kALtifMpPCZU80HvwztIKnYwym3KnA1os6nsX4BGSTLtS2QVAGG1P3guRgsYyMA0Yhg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.26.0.tgz", + "integrity": "sha512-WUQzVFWPSw2uJzX4j6YEbMAiLbs0BUysgysh8s817doAYhR5ybqTI1wtKARQKo6cGop3pHnrUJPFCsXdoFaimQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.26.0.tgz", + "integrity": "sha512-D4CxkazFKBfN1akAIY6ieyOqzoOoBV1OICxgUblWxff/pSjCA2khXlASUx7mK6W1oP4McqhgcCsu6QaLj3WMWg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.26.0.tgz", + "integrity": "sha512-2x8MO1rm4PGEP0xWbubJW5RtbNLk3puzAMaLQd3B3JHVw4KcHlmXcO+Wewx9zCoo7EUFiMlu/aZbCJ7VjMzAag==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@schematics/angular": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-19.0.6.tgz", + "integrity": "sha512-HicclmbW/+mlljU7a4PzbyIWG+7tognoL5LsgMFJQUDzJXHNjRt1riL0vk57o8Pcprnz9FheeWZXO1KRhXkQuw==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "19.0.6", + "@angular-devkit/schematics": "19.0.6", + "jsonc-parser": "3.3.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@schematics/angular/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@schematics/angular/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@schematics/angular/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@sigstore/bundle": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-3.0.0.tgz", + "integrity": "sha512-XDUYX56iMPAn/cdgh/DTJxz5RWmqKV4pwvUAEKEWJl+HzKdCd/24wUa9JYNMlDSCb7SUHAdtksxYX779Nne/Zg==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-2.0.0.tgz", + "integrity": "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.2.tgz", + "integrity": "sha512-c6B0ehIWxMI8wiS/bj6rHMPqeFvngFV7cDU/MY+B16P9Z3Mp9k8L93eYZ7BYzSickzuqAQqAq0V956b3Ju6mLw==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-3.0.0.tgz", + "integrity": "sha512-UjhDMQOkyDoktpXoc5YPJpJK6IooF2gayAr5LvXI4EL7O0vd58okgfRcxuaH+YTdhvb5aa1Q9f+WJ0c2sVuYIw==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^14.0.1", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-3.0.0.tgz", + "integrity": "sha512-9Xxy/8U5OFJu7s+OsHzI96IX/OzjF/zj0BSSaWhgJgTqtlBhQIV2xdrQI5qxLD7+CWWDepadnXAxzaZ3u9cvRw==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2", + "tuf-js": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-2.0.0.tgz", + "integrity": "sha512-Ggtq2GsJuxFNUvQzLoXqRwS4ceRfLAJnrIHUDrzAD0GgnOhwujJkKkxM/s5Bako07c3WtAs/sZo5PJq7VHjeDg==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-3.0.1.tgz", + "integrity": "sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==", + "dev": true, + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@tufjs/models/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/cors": { + "version": "2.8.17", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.2.tgz", + "integrity": "sha512-vluaspfvWEtE4vcSDlKRNer52DvOGrB2xv6diXy6UKyKW0lqZiWHGNApSyxOv+8DE5Z27IzVvE7hNkxg7EXIcg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/express/node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/jasmine": { + "version": "5.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.12.13", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.9.17", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", + "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.1.0.tgz", + "integrity": "sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A==", + "dev": true, + "engines": { + "node": ">=14.6.0" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-loader": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", + "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", + "dev": true, + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.3", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.3" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/base64id": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/beasties": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.1.0.tgz", + "integrity": "sha512-+Ssscd2gVG24qRNC+E2g88D+xsQW4xwakWtKAiGEQ3Pw54/FGdyo9RrfxhGhEv6ilFVbB7r3Lgx+QnAxnSpECw==", + "dev": true, + "dependencies": { + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "htmlparser2": "^9.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-media-query-parser": "^0.2.3" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "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==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz", + "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==", + "dev": true, + "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.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz", + "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^4.0.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001690", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", + "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", + "dev": true, + "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/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/chokidar": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "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" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "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/cli-truncate/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "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==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT" + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", + "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.0.2", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/connect": { + "version": "3.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.4.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/copy-anything": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", + "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", + "dev": true, + "dependencies": { + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.1", + "globby": "^14.0.0", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/core-js-compat": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", + "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==", + "dev": true, + "dependencies": { + "browserslist": "^4.24.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cors": { + "version": "2.8.5", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cosmiconfig/node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/cosmiconfig/node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", + "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", + "dev": true, + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "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==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/custom-event": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/date-format": { + "version": "4.0.14", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/di": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.75", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.75.tgz", + "integrity": "sha512-Lf3++DumRE/QmweGjU+ZcKqQ+3bKkU/qjaKYhIJKEOhgIO9Xs6IiAQFkfFoj+RhgDk4LUeNsLo6plExHqSyu6Q==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/engine.io": { + "version": "6.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", + "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ent": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/entities": { + "version": "4.5.0", + "devOptional": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "node_modules/errno": { + "version": "0.1.8", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.3", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz", + "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.0", + "@esbuild/android-arm": "0.24.0", + "@esbuild/android-arm64": "0.24.0", + "@esbuild/android-x64": "0.24.0", + "@esbuild/darwin-arm64": "0.24.0", + "@esbuild/darwin-x64": "0.24.0", + "@esbuild/freebsd-arm64": "0.24.0", + "@esbuild/freebsd-x64": "0.24.0", + "@esbuild/linux-arm": "0.24.0", + "@esbuild/linux-arm64": "0.24.0", + "@esbuild/linux-ia32": "0.24.0", + "@esbuild/linux-loong64": "0.24.0", + "@esbuild/linux-mips64el": "0.24.0", + "@esbuild/linux-ppc64": "0.24.0", + "@esbuild/linux-riscv64": "0.24.0", + "@esbuild/linux-s390x": "0.24.0", + "@esbuild/linux-x64": "0.24.0", + "@esbuild/netbsd-x64": "0.24.0", + "@esbuild/openbsd-arm64": "0.24.0", + "@esbuild/openbsd-x64": "0.24.0", + "@esbuild/sunos-x64": "0.24.0", + "@esbuild/win32-arm64": "0.24.0", + "@esbuild/win32-ia32": "0.24.0", + "@esbuild/win32-x64": "0.24.0" + } + }, + "node_modules/esbuild-wasm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.24.0.tgz", + "integrity": "sha512-xhNn5tL1AhkPg4ft59yXT6FkwKXiPSYyz1IeinJHUJpjvOHOIPvdmFQc0pGdjxlKSbzZc2mNmtVOWAR1EF/JAg==", + "dev": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dev": true, + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/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==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", + "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "function-bind": "^1.1.2", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "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", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "dev": true, + "license": "BSD-2-Clause" + }, + "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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "dev": true, + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.0.2.tgz", + "integrity": "sha512-sYKnA7eGln5ov8T8gnYlkSOxFJvywzEx9BueN6xo/GKO8PGiI6uK6xx+DIGe45T3bdVjLAQDQW1aicT8z8JwQg==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "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==", + "dev": true + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-middleware": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.3.tgz", + "integrity": "sha512-usY0HG5nyDUwtqpiZdETNbmKtw3QQ1jwYFZ9wi5iHzX2BcILwQKtYDJPo7XHTsu5Z0B2Hj3W9NNnbd+AjFWjqg==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.15", + "debug": "^4.3.6", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.3", + "is-plain-object": "^5.0.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-middleware/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-7.0.0.tgz", + "integrity": "sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ==", + "dev": true, + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ignore-walk/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immutable": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "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-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "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": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jasmine-core": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.0", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "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==", + "dev": true + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", + "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/karma": { + "version": "6.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.7.2", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-chrome-launcher": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "which": "^1.2.1" + } + }, + "node_modules/karma-coverage": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.0.5", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/karma-jasmine": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "jasmine-core": "^4.1.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "karma": "^6.0.0" + } + }, + "node_modules/karma-jasmine-html-reporter": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "peerDependencies": { + "jasmine-core": "^4.0.0 || ^5.0.0", + "karma": "^6.0.0", + "karma-jasmine": "^5.0.0" + } + }, + "node_modules/karma-jasmine/node_modules/jasmine-core": { + "version": "4.6.1", + "dev": true, + "license": "MIT" + }, + "node_modules/karma-source-map-support": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map-support": "^0.5.5" + } + }, + "node_modules/karma/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/karma/node_modules/cliui": { + "version": "7.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/karma/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/karma/node_modules/tmp": { + "version": "0.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/karma/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/karma/node_modules/yargs": { + "version": "16.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/karma/node_modules/yargs-parser": { + "version": "20.2.9", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/launch-editor": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/less": { + "version": "4.2.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less-loader": { + "version": "12.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "less": "^3.5.0 || ^4.0.0", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/less/node_modules/make-dir": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/mime": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/less/node_modules/semver": { + "version": "5.7.2", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/less/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/license-webpack-plugin": { + "version": "4.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "webpack-sources": "^3.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-sources": { + "optional": true + } + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", + "integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "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/listr2/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/lmdb": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.1.5.tgz", + "integrity": "sha512-46Mch5Drq+A93Ss3gtbg+Xuvf5BOgIuvhKDWoGa3HcPHI6BL2NCOkRdSx1D4VfzwrxhnsjbyIVsLRlQHu6URvw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "msgpackr": "^1.11.2", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.2.2", + "ordered-binary": "^1.5.3", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "3.1.5", + "@lmdb/lmdb-darwin-x64": "3.1.5", + "@lmdb/lmdb-linux-arm": "3.1.5", + "@lmdb/lmdb-linux-arm64": "3.1.5", + "@lmdb/lmdb-linux-x64": "3.1.5", + "@lmdb/lmdb-win32-x64": "3.1.5" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/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==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "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/log-update/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/log4js": { + "version": "6.9.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-fetch-happen": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", + "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==", + "dev": true, + "dependencies": { + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/make-fetch-happen/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.15.1.tgz", + "integrity": "sha512-ufCzgFwiVnR6R9cCYuvwznJdhdYXEvFl0hpnM4cCtVaVkHuqBR+6fo2sqt1SSMdp+uiHw9GyPZr3OMM5tqjSmQ==", + "dev": true, + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.3.0", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", + "dev": true, + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.0.tgz", + "integrity": "sha512-2v6aXUXwLP1Epd/gc32HAMIWoczx+fZwEPRHm/VwtrJzRGwR1qGZXEYV3Zp8ZjjbwaZhMrM6uHV4KVkk+XCc2w==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/minizlib/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/minizlib/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minizlib/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minizlib/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/msgpackr": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz", + "integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==", + "dev": true, + "optional": true, + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/needle": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "optional": true + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.0.0.tgz", + "integrity": "sha512-zQS+9MTTeCMgY0F3cWPyJyRFAkVltQ1uXm+xXu/ES6KFgC6Czo1Seb9vQW2wNxSX2OrDTiqL0ojtkFxBQ0ypIw==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^14.0.3", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "tar": "^7.4.3", + "which": "^5.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-gyp/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/node-gyp/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/node-gyp/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true + }, + "node_modules/nopt": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.0.0.tgz", + "integrity": "sha512-1L/fTJ4UmV/lUxT2Uf006pfZKTvAgCF+chz+0OgBHO8u2Z67pE7AaAUUj7CJy0lXqHmymUvGFt6NE9R3HER0yw==", + "dev": true, + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/normalize-package-data": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-7.0.0.tgz", + "integrity": "sha512-k6U0gKRIuNCTkwHGZqblCfLfBRh+w1vI6tBo+IeJwq2M8FUiOqhX7GH+GArQGScA7azd1WfyRCvxoXDO3hQDIA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^8.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-bundled": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-4.0.0.tgz", + "integrity": "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA==", + "dev": true, + "dependencies": { + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-install-checks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-7.1.1.tgz", + "integrity": "sha512-u6DCwbow5ynAX5BdiHQ9qvexme4U3qHW3MWe5NqH+NeBm0LbiH6zvGjNNew1fY+AZZUtVHbOPF3j7mJxbUzpXg==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", + "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-package-arg": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.0.tgz", + "integrity": "sha512-ZTE0hbwSdTNL+Stx2zxSqdu2KZfNDcrtrLdIk7XGnQFYBWYDho/ORvXtn5XEePcL3tFpGjHCV3X3xrtDh7eZ+A==", + "dev": true, + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-packlist": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-9.0.0.tgz", + "integrity": "sha512-8qSayfmHJQTx3nJWYbbUmflpyarbLMBc6LCAjYsiGtXxDB68HaZpb8re6zeaLGxZzDuMdhsg70jryJe+RrItVQ==", + "dev": true, + "dependencies": { + "ignore-walk": "^7.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-10.0.0.tgz", + "integrity": "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==", + "dev": true, + "dependencies": { + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-18.0.2.tgz", + "integrity": "sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ==", + "dev": true, + "dependencies": { + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.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==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ordered-binary": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.3.tgz", + "integrity": "sha512-oGFr3T+pYdTGJ+YFEILMpS3es+GiIbs9h/XQrclBXUtd44ey7XwfsMzM31f64I1SQOawDoDr/D823kNCADI8TA==", + "dev": true, + "optional": true + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", + "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, + "node_modules/pacote": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-20.0.0.tgz", + "integrity": "sha512-pRjC5UFwZCgx9kUFDVM9YEahv4guZ1nSLqwmWiLUnDbGsjs+U5w7z6Uc8HNR1a6x8qnu5y9xtGE6D1uAuYz+0A==", + "dev": true, + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "devOptional": true, + "license": "MIT", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz", + "integrity": "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==", + "dev": true, + "dependencies": { + "entities": "^4.3.0", + "parse5": "^7.0.0", + "parse5-sax-parser": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-sax-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", + "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==", + "dev": true, + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true + }, + "node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/picomatch": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/piscina": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.7.0.tgz", + "integrity": "sha512-b8hvkpp9zS0zsfa939b/jXbe64Z2gZv0Ha7FYPNUiDIB1y2AtxcOZdfP8xN8HFjUaqQiT9gRlfjAsoL8vdJ1Iw==", + "dev": true, + "optionalDependencies": { + "@napi-rs/nice": "^1.0.1" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dev": true, + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "dev": true, + "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.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-loader": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cosmiconfig": "^9.0.0", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/punycode": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qjobs": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.9" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-parser": { + "version": "2.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/regexpu-core": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dev": true, + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.8", + "dev": true, + "license": "MIT", + "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-url-loader": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/resolve-url-loader/node_modules/loader-utils": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true + }, + "node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.26.0.tgz", + "integrity": "sha512-ilcl12hnWonG8f+NxU6BlgysVA0gvY2l8N0R84S1HcINbW20bvwuCngJkkInV6LXhwRpucsW5k1ovDwEdBVrNg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.26.0", + "@rollup/rollup-android-arm64": "4.26.0", + "@rollup/rollup-darwin-arm64": "4.26.0", + "@rollup/rollup-darwin-x64": "4.26.0", + "@rollup/rollup-freebsd-arm64": "4.26.0", + "@rollup/rollup-freebsd-x64": "4.26.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.26.0", + "@rollup/rollup-linux-arm-musleabihf": "4.26.0", + "@rollup/rollup-linux-arm64-gnu": "4.26.0", + "@rollup/rollup-linux-arm64-musl": "4.26.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.26.0", + "@rollup/rollup-linux-riscv64-gnu": "4.26.0", + "@rollup/rollup-linux-s390x-gnu": "4.26.0", + "@rollup/rollup-linux-x64-gnu": "4.26.0", + "@rollup/rollup-linux-x64-musl": "4.26.0", + "@rollup/rollup-win32-arm64-msvc": "4.26.0", + "@rollup/rollup-win32-ia32-msvc": "4.26.0", + "@rollup/rollup-win32-x64-msvc": "4.26.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.80.7", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.7.tgz", + "integrity": "sha512-MVWvN0u5meytrSjsU7AWsbhoXi1sc58zADXFllfZzbsBT1GHjjar6JwBINYPRrkx/zqnQ6uqbQuHgE95O+C+eQ==", + "dev": true, + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass-loader": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.3.tgz", + "integrity": "sha512-gosNorT1RCkuCMyihv6FBRR7BMV06oKRAs+l4UMp1mlcVg9rWN6KMmUj3igjQwmYys4mDP3etEYJgiHRbgHCHA==", + "dev": true, + "dependencies": { + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sass/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sax": { + "version": "1.4.1", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.6.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dev": true, + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/sigstore": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-3.0.0.tgz", + "integrity": "sha512-PHMifhh3EN4loMcHCz6l3v/luzgT3za+9f8subGgeMNjbJjzH4Ij/YoX3Gvu+kaouJRIlVdTHHCREADYf+ZteA==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/sign": "^3.0.0", + "@sigstore/tuf": "^3.0.0", + "@sigstore/verify": "^2.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socket.io": { + "version": "4.7.5", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.5.2", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "~4.3.4", + "ws": "~8.11.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "dev": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" + } + }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "dev": true + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, + "node_modules/ssri": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz", + "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "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==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-observable": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "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/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==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/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==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/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==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "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==", + "dev": true + }, + "node_modules/terser": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", + "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "dev": true, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tree-dump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", + "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/tuf-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-3.0.1.tgz", + "integrity": "sha512-+68OP1ZzSF84rTckf3FA95vJ1Zlx/uaXyiiKyPd1pA4rZNkpEvDAKmsu1xUSmbF/chCRYgZ6UZkDwC7PmzmAyA==", + "dev": true, + "dependencies": { + "@tufjs/models": "3.0.1", + "debug": "^4.3.6", + "make-fetch-happen": "^14.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/tuf-js/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/tuf-js/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-assert": { + "version": "1.0.9", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.38", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "dev": true, + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unique-filename": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz", + "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==", + "dev": true, + "dependencies": { + "unique-slug": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/unique-slug": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz", + "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "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.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.0.tgz", + "integrity": "sha512-d7KLgL1LD3U3fgnvWEY1cQXoO/q6EQ1BSz48Sa149V/5zVTAbgmZIpyI8TRi6U9/JNyeYLlTKsEMPtLC27RFUg==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "5.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.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": "*", + "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 + } + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "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" + } + }, + "node_modules/void-elements": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true, + "optional": true + }, + "node_modules/webpack": { + "version": "5.96.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.96.1.tgz", + "integrity": "sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "dev": true, + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.1.0.tgz", + "integrity": "sha512-aQpaN81X6tXie1FoOB7xlMfCsN19pSvRAeYUHOdFWOlhpQ/LlbfTqYwwmEDFV0h8GGuqmCmKmT+pxcUV/Nt2gQ==", + "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.19.2", + "graceful-fs": "^4.2.6", + "html-entities": "^2.4.0", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-subresource-integrity": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "typed-assert": "^1.0.8" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", + "webpack": "^5.12.0" + }, + "peerDependenciesMeta": { + "html-webpack-plugin": { + "optional": true + } + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.11.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zone.js": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.0.tgz", + "integrity": "sha512-9oxn0IIjbCZkJ67L+LkhYWRyAy7axphb3VgE2MBDlOqnmHMPWGYMxJxBYFueFq/JGY2GMwS0rU+UCLunEmy5UA==" + } + } +} diff --git a/examples/angular-cli-material/package.json b/examples/angular-cli-material/package.json new file mode 100644 index 00000000..20571785 --- /dev/null +++ b/examples/angular-cli-material/package.json @@ -0,0 +1,45 @@ +{ + "name": "angular-cli", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "npm run build:dev", + "build:dev": "ng build --configuration development", + "build:prod": "ng build --configuration production", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "dependencies": { + "@angular/animations": "^19.0.5", + "@angular/cdk": "^19.0.4", + "@angular/common": "^19.0.5", + "@angular/compiler": "^19.0.5", + "@angular/core": "^19.0.5", + "@angular/forms": "^19.0.5", + "@angular/material": "^19.0.4", + "@angular/platform-browser": "^19.0.5", + "@angular/platform-browser-dynamic": "^19.0.5", + "@angular/router": "^19.0.5", + "@fortawesome/fontawesome-svg-core": "^6.7.2", + "@fortawesome/free-solid-svg-icons": "^6.7.2", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^19.0.6", + "@angular/cli": "~19.0.6", + "@angular/compiler-cli": "^19.0.5", + "@types/jasmine": "~5.1.0", + "@types/node": "^20.10.0", + "jasmine-core": "~5.1.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.6.3" + } +} diff --git a/examples/angular-cli-material/src/app/app-routing.module.ts b/examples/angular-cli-material/src/app/app-routing.module.ts new file mode 100644 index 00000000..20be26e4 --- /dev/null +++ b/examples/angular-cli-material/src/app/app-routing.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { ModalGalleryExampleComponent } from './modal-gallery/modal-gallery.component'; +import { PlainGalleryExampleComponent } from './plain-gallery/plain-gallery.component'; +import { CarouselExampleComponent } from './carousel/carousel.component'; +import { HomeComponent } from './home/home.component'; + +const routes: Routes = [ + { path: '', component: HomeComponent }, + { path: 'carousel', component: CarouselExampleComponent }, + { path: 'modal', component: ModalGalleryExampleComponent }, + { path: 'plain', component: PlainGalleryExampleComponent } +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes)], + exports: [RouterModule] +}) +export class AppRoutingModule {} diff --git a/examples/angular-cli-material/src/app/app.component.html b/examples/angular-cli-material/src/app/app.component.html new file mode 100644 index 00000000..3811d780 --- /dev/null +++ b/examples/angular-cli-material/src/app/app.component.html @@ -0,0 +1,87 @@ + + +

+ + + +

+

Example of Angular Material

+ + + {{tile.text}} + + +
    +
  1. + + What's your name? + + +
  2. +
  3. + +
  4. +
  5. + You chose: {{animal}} +
  6. +
+ +
+ +

+
+ + +
+

A special thank to all authors of icons used in this library:

+ +
+ +
+

A special thanks to all authors of spinners used in this library:

+ +
diff --git a/examples/angular-cli-material/src/app/app.component.scss b/examples/angular-cli-material/src/app/app.component.scss new file mode 100644 index 00000000..e06277ac --- /dev/null +++ b/examples/angular-cli-material/src/app/app.component.scss @@ -0,0 +1,47 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + + +#main-title { + text-align: center; + width: 100%; +} + +#menu { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + + > .menu-item { + margin-left: 10px; + } +} + +.copyright { + text-align: center; +} + +.margin { + margin-left: 15px; + margin-right: 15px; +} diff --git a/examples/angular-cli-material/src/app/app.component.ts b/examples/angular-cli-material/src/app/app.component.ts new file mode 100644 index 00000000..9f490dea --- /dev/null +++ b/examples/angular-cli-material/src/app/app.component.ts @@ -0,0 +1,83 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component, Inject } from '@angular/core'; +import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; + +export interface DialogData { + animal: string; + name: string; +} + +@Component({ + selector: 'ks-root', + templateUrl: 'app.component.html', + styleUrls: ['app.component.scss'], + standalone: false +}) +export class AppComponent { + // ---------------------------------------------------- + // ---------------------------------------------------- + tiles = [ + { text: 'One', cols: 3, rows: 1, color: 'lightblue' }, + { text: 'Two', cols: 1, rows: 2, color: 'lightgreen' }, + { text: 'Three', cols: 1, rows: 1, color: 'lightpink' }, + { text: 'Four', cols: 2, rows: 1, color: '#DDBDF1' } + ]; + + animal: string | undefined; + name: string | undefined; + + constructor(public dialog: MatDialog) {} + + openDialog(): void { + const dialogRef = this.dialog.open(DialogOverviewExampleDialog, { + width: '250px', + data: { name: this.name, animal: this.animal } + }); + + dialogRef.afterClosed().subscribe((result: any) => { + console.log('The dialog was closed'); + this.animal = result; + }); + } +} + +// ---------------------------------------------------- +// ---------------------------------------------------- +@Component({ + selector: 'dialog-overview-example-dialog', + templateUrl: 'dialog-overview-example-dialog.html', + standalone: false +}) +export class DialogOverviewExampleDialog { + constructor(public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: DialogData) {} + + onNoClick(): void { + this.dialogRef.close(); + } +} +// ---------------------------------------------------- +// ---------------------------------------------------- + diff --git a/examples/angular-cli-material/src/app/app.module.ts b/examples/angular-cli-material/src/app/app.module.ts new file mode 100644 index 00000000..ada7ac81 --- /dev/null +++ b/examples/angular-cli-material/src/app/app.module.ts @@ -0,0 +1,88 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; + +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; +import { DialogOverviewExampleDialog } from './app.component'; +import { CarouselExampleComponent } from './carousel/carousel.component'; +import { PlainGalleryExampleComponent } from './plain-gallery/plain-gallery.component'; +import { ModalGalleryExampleComponent } from './modal-gallery/modal-gallery.component'; +import { NavbarComponent } from './navbar/navbar.component'; +import { HomeComponent } from './home/home.component'; +import { IntroHeaderComponent } from './intro-header/intro-header.component'; + +// ********************** angular-modal-gallery ***************************** +import { GalleryModule } from '@ks89/angular-modal-gallery'; // <----------------- angular-modal-gallery library import +// ************************************************************************** + +// ************************ optional font-awesome 5 ************************ +// to install use both `npm i --save @fortawesome/fontawesome-svg-core` and `npm i --save @fortawesome/free-solid-svg-icons` +import { library, dom } from '@fortawesome/fontawesome-svg-core'; +import { faExternalLinkAlt, faPlus, faTimes, faDownload } from '@fortawesome/free-solid-svg-icons'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +library.add(faExternalLinkAlt, faPlus, faTimes, faDownload); +dom.watch(); // Kicks off the process of finding tags and replacing with +// ************************************************************************* + +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatInputModule } from '@angular/material/input'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatFormFieldModule } from '@angular/material/form-field'; + +@NgModule({ + declarations: [ + AppComponent, + CarouselExampleComponent, + PlainGalleryExampleComponent, + ModalGalleryExampleComponent, + NavbarComponent, + HomeComponent, + IntroHeaderComponent, + DialogOverviewExampleDialog + ], + imports: [ + BrowserModule, + BrowserAnimationsModule, + FormsModule, + ReactiveFormsModule, + + MatButtonModule, + MatGridListModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + + AppRoutingModule, + + GalleryModule // <-------------------------------------------- @ks89/angular-modal-gallery module import + ], + providers: [], + bootstrap: [AppComponent] +}) +export class AppModule {} diff --git a/examples/angular-cli-material/src/app/carousel/carousel.component.ts b/examples/angular-cli-material/src/app/carousel/carousel.component.ts new file mode 100644 index 00000000..28f51e12 --- /dev/null +++ b/examples/angular-cli-material/src/app/carousel/carousel.component.ts @@ -0,0 +1,566 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component } from '@angular/core'; + +import { AccessibilityConfig, CarouselLibConfig, Image, ImageEvent, ModalGalleryConfig, ModalGalleryRef, ModalGalleryService, ModalLibConfig } from '@ks89/angular-modal-gallery'; + +@Component({ + selector: 'ks-carousel-page', + templateUrl: './carousel.html', + styleUrls: ['./carousel.scss'], + standalone: false +}) +export class CarouselExampleComponent { + imageIndex = 1; + galleryId = 1; + autoPlay = true; + showArrows = true; + showDots = true; + + LIBCONFIG102: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: false + } + }; + LIBCONFIG103: CarouselLibConfig = { + carouselSlideInfinite: false + }; + LIBCONFIG104: CarouselLibConfig = { + carouselDotsConfig: { + visible: false + } + }; + LIBCONFIG105: CarouselLibConfig = { + carouselPlayConfig: { + autoPlay: false, + interval: 5000, + pauseOnHover: true + } + }; + LIBCONFIG106: CarouselLibConfig = { + carouselPlayConfig: { + autoPlay: true, + interval: 10000, + pauseOnHover: false + } + }; + LIBCONFIG107: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 7, + width: 'auto', + maxHeight: '100px' + } + }; + LIBCONFIG113: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 5 + }, + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + } + }; + LIBCONFIG114: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 5, + width: 'auto', + maxHeight: '100px' + }, + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: true + } + }; + LIBCONFIG115: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 5, + width: 'auto', + maxHeight: '100px' + }, + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: false, + modalGalleryEnable: false + } + }; + LIBCONFIG116: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 7, + clickable: false + } + }; + LIBCONFIG117: CarouselLibConfig = { + carouselImageConfig: { + invertSwipe: true + } + }; + LIBCONFIG118: CarouselLibConfig = { + carouselImageConfig: { + description: { + strategy: 2 + } + } + }; + LIBCONFIG119: CarouselLibConfig = { + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + }, + carouselPreviewsConfig: { + visible: true, + number: 5, + width: 'auto', + maxHeight: '200px' + } + }; + LIBCONFIG120: CarouselLibConfig = { + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + }, + carouselPreviewsConfig: { + visible: true, + number: 5, + width: 'auto', + maxHeight: '150px' + } + }; + LIBCONFIG121: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + breakpoints: { + xSmall: 50, + small: 60, + medium: 80, + large: 150, + xLarge: 180 + } + } + }; + LIBCONFIG122: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + breakpoints: { + xSmall: 50, + small: 60, + medium: 70, + large: 80, + xLarge: 100 + } + }, + carouselConfig: { + maxWidth: '500px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + } + }; + LIBCONFIG124: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + breakpoints: { + xSmall: 50, + small: 60, + medium: 70, + large: 80, + xLarge: 100 + } + }, + carouselConfig: { + maxWidth: '500px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + }, + carouselPlayConfig: { + autoPlay: false, + interval: 1, + pauseOnHover: true + } + }; + + imagesRect: Image[] = [ + new Image( + 0, + { + img: '/assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1' + }, + { + img: '/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', + title: 'First image title', + alt: 'First image alt', + ariaLabel: 'First image aria-label' + } + ), + new Image(1, { img: '/assets/images/gallery/pexels-photo-47223.jpeg' }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg' }), + new Image( + 2, + { + img: '/assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3', + title: 'Third image title', + alt: 'Third image alt', + ariaLabel: 'Third image aria-label' + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '/assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4', + title: 'Fourth image title (modal obj)', + alt: 'Fourth image alt (modal obj)', + ariaLabel: 'Fourth image aria-label (modal obj)' + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', + title: 'Fourth image title (plain obj)', + alt: 'Fourth image alt (plain obj)', + ariaLabel: 'Fourth image aria-label (plain obj)' + } + ), + new Image(4, { img: '/assets/images/gallery/pexels-photo-93750.jpeg' }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg' }), + new Image( + 5, + { + img: '/assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6' + }, + { img: '/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg' } + ), + new Image(6, { img: '/assets/images/gallery/pexels-photo-96947.jpeg' }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg' }) + ]; + + imagesRectWithSources: Image[] = [ + new Image( + 0, + { + img: '/assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/milan-pegasus-gallery-statue-480w.jpg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/milan-pegasus-gallery-statue-768w.jpg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/milan-pegasus-gallery-statue-1024w.jpg' } + ] + }, + { + img: '/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', + title: 'First image title', + alt: 'First image alt', + ariaLabel: 'First image aria-label' + } + ), + new Image(1, { img: '/assets/images/gallery/pexels-photo-47223.jpeg', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-47223-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-47223-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-47223-1024w.jpeg' } + ] }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg' }), + new Image( + 2, + { + img: '/assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3', + title: 'Third image title', + alt: 'Third image alt', + ariaLabel: 'Third image aria-label', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-52062-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-52062-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-52062-1024w.jpeg' } + ] + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '/assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4', + title: 'Fourth image title (modal obj)', + alt: 'Fourth image alt (modal obj)', + ariaLabel: 'Fourth image aria-label (modal obj)', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-66943-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-66943-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-66943-1024w.jpeg' } + ] + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', + title: 'Fourth image title (plain obj)', + alt: 'Fourth image alt (plain obj)', + ariaLabel: 'Fourth image aria-label (plain obj)' + } + ), + new Image(4, { img: '/assets/images/gallery/pexels-photo-93750.jpeg', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-93750-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-93750-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-93750-1024w.jpeg' } + ] }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg' }), + new Image( + 5, + { + img: '/assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-94420-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-94420-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-94420-1024w.jpeg' } + ] + }, + { img: '/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg' } + ), + new Image(6, { img: '/assets/images/gallery/pexels-photo-96947.jpeg', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-96947-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-96947-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-96947-1024w.jpeg' } + ] }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg' }) + ]; + emptyImagesArray: Image[] = []; + + imagesRectNoTitles: Image[] = [ + new Image( + 0, + { img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', title: '' } + ), + new Image( + 1, + { img: '../assets/images/gallery/pexels-photo-47223.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg', title: '' } + ), + new Image( + 2, + { img: '../assets/images/gallery/pexels-photo-52062.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', title: '' } + ), + new Image( + 3, + { img: '../assets/images/gallery/pexels-photo-66943.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', title: '' } + ), + new Image( + 4, + { img: '../assets/images/gallery/pexels-photo-93750.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg', title: '' } + ), + new Image( + 5, + { img: '../assets/images/gallery/pexels-photo-94420.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg', title: '' } + ), + new Image( + 6, + { img: '../assets/images/gallery/pexels-photo-96947.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg', title: '' } + ) + ]; + + fallbackRectImages: Image[] = [ + new Image(0, { + // this file is not available so the browser returns an error + img: '../assets/images/gallery/UNEXISTING_IMG1.jpg', + // because the img above doesn't exists, the library will use this file + fallbackImg: '../assets/images/gallery/fallback-carousel1.jpg' + }), + new Image(1, { + img: '../assets/images/gallery/UNEXISTING_IMG2.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel2.jpg' + }), + new Image( + 2, + { + img: '../assets/images/gallery/UNEXISTING_IMG3.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel3.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG3.png', + fallbackImg: '../assets/images/gallery/fallback-carousel3.jpg' + } + ), + new Image(3, { + img: '../assets/images/gallery/UNEXISTING_IMG4.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel4.jpg' + }), + new Image( + 4, + { + img: '../assets/images/gallery/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel5.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel5.jpg' + } + ) + ]; + + accessibilityConfig: AccessibilityConfig = { + backgroundAriaLabel: 'CUSTOM Modal gallery full screen background', + backgroundTitle: 'CUSTOM background title', + + plainGalleryContentAriaLabel: 'CUSTOM Plain gallery content', + plainGalleryContentTitle: 'CUSTOM plain gallery content title', + + modalGalleryContentAriaLabel: 'CUSTOM Modal gallery content', + modalGalleryContentTitle: 'CUSTOM modal gallery content title', + + loadingSpinnerAriaLabel: 'CUSTOM The current image is loading. Please be patient.', + loadingSpinnerTitle: 'CUSTOM The current image is loading. Please be patient.', + + mainContainerAriaLabel: 'CUSTOM Current image and navigation', + mainContainerTitle: 'CUSTOM main container title', + mainPrevImageAriaLabel: 'CUSTOM Previous image', + mainPrevImageTitle: 'CUSTOM Previous image', + mainNextImageAriaLabel: 'CUSTOM Next image', + mainNextImageTitle: 'CUSTOM Next image', + + dotsContainerAriaLabel: 'CUSTOM Image navigation dots', + dotsContainerTitle: 'CUSTOM dots container title', + dotAriaLabel: 'CUSTOM Navigate to image number', + + previewsContainerAriaLabel: 'CUSTOM Image previews', + previewsContainerTitle: 'CUSTOM previews title', + previewScrollPrevAriaLabel: 'CUSTOM Scroll previous previews', + previewScrollPrevTitle: 'CUSTOM Scroll previous previews', + previewScrollNextAriaLabel: 'CUSTOM Scroll next previews', + previewScrollNextTitle: 'CUSTOM Scroll next previews', + + carouselContainerAriaLabel: 'Current image and navigation', + carouselContainerTitle: '', + carouselPrevImageAriaLabel: 'Previous image', + carouselPrevImageTitle: 'Previous image', + carouselNextImageAriaLabel: 'Next image', + carouselNextImageTitle: 'Next image', + carouselPreviewsContainerAriaLabel: 'Image previews', + carouselPreviewsContainerTitle: '', + carouselPreviewScrollPrevAriaLabel: 'Scroll previous previews', + carouselPreviewScrollPrevTitle: 'Scroll previous previews', + carouselPreviewScrollNextAriaLabel: 'Scroll next previews', + carouselPreviewScrollNextTitle: 'Scroll next previews' + }; + + constructor(private modalGalleryService: ModalGalleryService) {} + + addRandomImage(): void { + const imageToCopy: Image = this.imagesRect[Math.floor(Math.random() * this.imagesRect.length)]; + const newImage: Image = new Image(this.imagesRect.length - 1 + 1, imageToCopy.modal, imageToCopy.plain); + this.imagesRect = [...this.imagesRect, newImage]; + } + + onChangeAutoPlay(): void { + this.autoPlay = !this.autoPlay; + } + + onChangeShowArrows(): void { + this.showArrows = !this.showArrows; + } + + onChangeShowDots(): void { + this.showDots = !this.showDots; + } + + // output evets + onShow(event: ImageEvent): void { + console.log('show', event); + } + + onFirstImage(event: ImageEvent): void { + console.log('firstImage', event); + } + + onLastImage(event: ImageEvent): void { + console.log('lastImage', event); + } + + getLibConfig108(autoPlay: boolean, showArrows: boolean, showDots: boolean): CarouselLibConfig { + return { + carouselDotsConfig: { + visible: showDots + }, + carouselPlayConfig: { + autoPlay: autoPlay, + interval: 3000, + pauseOnHover: true + }, + carouselConfig: { + maxWidth: '100%', + maxHeight: '400px', + showArrows: showArrows, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + } + } as CarouselLibConfig; + } + + openModal(imageIndex: number, id: number): void { + const imageToShow: Image = this.imagesRect[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: this.imagesRect, + currentImage: imageToShow + } as ModalGalleryConfig) as ModalGalleryRef; + } +} diff --git a/examples/angular-cli-material/src/app/carousel/carousel.html b/examples/angular-cli-material/src/app/carousel/carousel.html new file mode 100644 index 00000000..ee04ac8c --- /dev/null +++ b/examples/angular-cli-material/src/app/carousel/carousel.html @@ -0,0 +1,215 @@ +

Carousel

+
+ +

Basic examples

+
+
+

A1 - (id=100) - carousel example (minimal with all defaults) without content projection

+
+ +
+
+
+

A2 - (id=101) - carousel example (minimal with all defaults)

+
+ +
This is my projected content!
+
+
+
+
+

A3 - (id=102) - carousel example without previews

+
+ +
This is my projected content!
+
+
+
+
+

A4 - (id=103) - carousel example without infinite sliding

+
+ +
This is my projected content!
+
+
+
+
+

A5 - (id=104) - carousel example without dots

+
+ +
This is my projected content!
+
+
+
+
+

A6 - (id=105) - carousel example without auto-play (but all other playConfig properties have default values)

+
+ +
This is my projected content!
+
+
+
+
+

A7 - (id=106) - carousel example with a custom playConfig (10s of interval and pauseOnHover disabled)

+
+ +
This is my projected content!
+
+
+
+
+

A8 - (id=107) - carousel example with a custom previewConfig (7 previews with 'auto' width and 100px of height)

+
+ +
This is my projected content!
+
+
+
+
+

A9 - (id=108) - carousel example with buttons to enable/disable autoplay, arrows and other properties

+

Autoplay:

+

Show Arrows:

+

Show Dots:

+
+ +
This is my projected content!
+
+
+
+
+

A10 - (id=109) - carousel example (minimal with all defaults) with outputs

+
+ +
+
+
+

A11 - (id=110) - carousel example with fallback images when it's not possible to load normal images (to fix issue #194)

+
+ +
+
+
+

A12 - (id=111) - carousel example without title attribute on images

+
+ +
+
+
+

A13 - (id=112) - carousel example with an empty images array.

+

Carousel component doesn't support empty images arrays! To prevent runtime errors, you should use an *ngIf to remove the carousel when there are no images.

+
+ +
+
+
+ +

Examples with custom style

+
+

B1 - (id=113) - carousel example with fixed maxWidth (766px) and custom previews

+

By default, on bigger screen, previews will have height = 200px. If you want you can customize it or also change all breakpoint widths.

+
+ +
This is my projected content!
+
+
+
+
+

B2 - (id=114) - carousel example with fixed maxWidth (766px), custom previews and open modal on click

+
+ +
This is my projected content!
+
+
+
+
+

B3 - (id=115) - carousel example with fixed maxWidth (766px), custom previews and keyboard navigation disabled (for example left/right arrows)

+
+ +
This is my projected content!
+
+
+
+
+

B4 - (id=116) - carousel example with 7 images and unclickable previews

+
+ +
This is my projected content!
+
+
+
+
+ +

Examples with custom current image

+
+

C1 - (id=117) - carousel example with invert swipe on touchscreen devices

+
+ +
This is my projected content!
+
+
+
+
+

C2 - (id=118) - carousel example with description

+
+ +
This is my projected content!
+
+
+
+ + +

Examples with custom previews height

+

I know that these examples look bad, but the purpose is to show only how the library handles heights. + In both examples I didn't set breakpoints, so it will be used default values, but with the maxHeight specified

+

If F1, the maxHeight is 200px, but also the default breakpoints has 200px as maximum size, so the result will be very bad on bigger screen. + In F2, I'm using a smaller maxHeight, so previews won't be taller than 150px, despite the default breakpoints on bigger screens (200px).

+
+

F1 - (id=119) - carousel example with fixed maxWidth (766px) and custom previews (maxHeight 200px)

+
+ +
This is my projected content!
+
+
+
+
+

F2 - (id=120) - carousel example with fixed maxWidth (766px) and custom previews (maxHeight 150px)

+
+ +
This is my projected content!
+
+
+
+ + +

Examples with custom heights for previews (to try responsiveness)

+
+
+

G1 - (id=121) - carousel example (previews with different heights based on the window's width: xSmall: 50, small: 60, medium: 80, large: 150, xLarge: 180)

+
+ +
+
+
+

G2 - (id=122) - carousel example with fixed maxWidth (500px) (previews with different heights based on the window's width: xSmall: 50, small: 60, medium: 70, large: 80, xLarge: 100)

+
+ +
+
+

Examples using sources (to improve LCP)

+
+
+

H1 - (id=123) - carousel example (minimal with all defaults) without content projection - using sources

+
+ +
+
+

H2 - (id=124) - carousel example with fixed maxWidth (500px) (previews with different heights based on the window's width: xSmall: 50, small: 60, medium: 70, large: 80, xLarge: 100) - using sources

+
+ +
+
+
diff --git a/examples/angular-cli-material/src/app/carousel/carousel.scss b/examples/angular-cli-material/src/app/carousel/carousel.scss new file mode 100644 index 00000000..547c14f9 --- /dev/null +++ b/examples/angular-cli-material/src/app/carousel/carousel.scss @@ -0,0 +1,157 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +:host { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; +} + +section { + width: 100%; +} + +h2, h3, p { + margin-left: 20px; +} + +$text-color: #fff; +$background: rgba(0, 0, 0, .7); + +.my-app-custom-plain-container-row { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + .my-app-custom-image-row { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-column { + align-items: center; + display: flex; + flex-direction: column; + justify-content: flex-start; + + .my-app-custom-image-column { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-with-desc { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + figure { + margin: 0; + position: relative; + + img { + max-width: 100%; + height: auto; + cursor: pointer; + } + + figcaption { + background: rgba(0, 0, 0, .5); + color: #fff; + font-size: 85%; + padding: 5px; + position: absolute; + bottom: 3px; + left: 0; + right: 0; + } + } + + .description { + font-weight: bold; + text-align: center; + } + + .my-app-custom-image-with-desc { + height: auto; + margin-right: 2px; + width: 200px; + align-self: start; + } +} + +.more { + background: $background; + cursor: pointer; + color: $text-color; + padding-top: 4px; + height: 46px; + position: absolute; + text-align: center; + width: 50px; +} + + +.projected { + color: white; + font-weight: 600; + font-size: 24px; + text-align: center; + position: absolute; + top: 50%; + width: 100%; + pointer-events: none; +} + +.title { + margin-top: 40px; +} diff --git a/examples/angular-cli-material/src/app/dialog-overview-example-dialog.html b/examples/angular-cli-material/src/app/dialog-overview-example-dialog.html new file mode 100644 index 00000000..3cff5c92 --- /dev/null +++ b/examples/angular-cli-material/src/app/dialog-overview-example-dialog.html @@ -0,0 +1,16 @@ +

Hi {{data.name}}

+
+

What's your favorite animal?

+ + Favorite Animal + + +
+
+ + +
+ + diff --git a/examples/angular-cli-material/src/app/home/home.component.ts b/examples/angular-cli-material/src/app/home/home.component.ts new file mode 100644 index 00000000..82d07f20 --- /dev/null +++ b/examples/angular-cli-material/src/app/home/home.component.ts @@ -0,0 +1,33 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component } from '@angular/core'; + +@Component({ + selector: 'ks-home-page', + templateUrl: './home.html', + styleUrls: ['./home.scss'], + standalone: false +}) +export class HomeComponent {} diff --git a/examples/angular-cli-material/src/app/home/home.html b/examples/angular-cli-material/src/app/home/home.html new file mode 100644 index 00000000..f5ec1261 --- /dev/null +++ b/examples/angular-cli-material/src/app/home/home.html @@ -0,0 +1,12 @@ + +
+ +
+

Welcome

+

This is the official live example of @ks89/angular-modal-gallery. + To get started quickly you can try and check the sourcecode of this example.

+

If you need the full documentation with all apis, this is the official documentation website.

+ +

The official documentation is available at ks89.github.io/angular-modal-gallery-2024-v13.github.io

+
+ diff --git a/examples/angular-cli-material/src/app/home/home.scss b/examples/angular-cli-material/src/app/home/home.scss new file mode 100644 index 00000000..8c5e86a7 --- /dev/null +++ b/examples/angular-cli-material/src/app/home/home.scss @@ -0,0 +1,26 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +.container { + margin-left: 15px; + margin-right: 15px; +} diff --git a/examples/angular-cli-material/src/app/intro-header/intro-header.component.ts b/examples/angular-cli-material/src/app/intro-header/intro-header.component.ts new file mode 100644 index 00000000..c2b1e55b --- /dev/null +++ b/examples/angular-cli-material/src/app/intro-header/intro-header.component.ts @@ -0,0 +1,33 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { Component } from '@angular/core'; + +@Component({ + selector: 'ks-intro-header', + templateUrl: 'intro-header.html', + styleUrls: ['intro-header.scss'], + standalone: false +}) +export class IntroHeaderComponent {} diff --git a/examples/angular-cli-material/src/app/intro-header/intro-header.html b/examples/angular-cli-material/src/app/intro-header/intro-header.html new file mode 100644 index 00000000..94cdd372 --- /dev/null +++ b/examples/angular-cli-material/src/app/intro-header/intro-header.html @@ -0,0 +1,8 @@ +
+ @ks89/angular-modal-gallery icon +

@ks89/angular-modal-gallery

+

Image gallery for Angular >=19

+

Currently v13

+
+
diff --git a/examples/angular-cli-material/src/app/intro-header/intro-header.scss b/examples/angular-cli-material/src/app/intro-header/intro-header.scss new file mode 100644 index 00000000..e0eeaf88 --- /dev/null +++ b/examples/angular-cli-material/src/app/intro-header/intro-header.scss @@ -0,0 +1,73 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// search all occurrences in all code, also html, because it's everywhere +$color-primary: #101010; +$color-secondary: #9e9e9e; +$color-white: #FFF; +$color-black: #000; +$color-light-black: #343A40; +$color-code: #c100e0; +$color-url: #0060b7; +$color-warning: #880012; + +//$font-huge: 24px; +$font-big: 18px; +$font-middle: 14px; +$font-small: 12px; +$font-very-small: 10px; + +.intro-header { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + background-color: $color-primary; + background: linear-gradient(135deg, $color-primary, $color-secondary); + margin-top: 10px; + padding-bottom: 1px; + color: $color-white; + + h1 { + color: $color-white; + font-size: 3rem; + } +} + +.project-title { + margin-top: 20px; + font-size: 2.8rem; + text-align: center; +} + +img { + margin-top: 25px; + border-radius: 10px +} + +.lead { + font-size: 1rem; + text-align: center; + color: #d4d4d4; +} diff --git a/examples/angular-cli-material/src/app/modal-gallery/libconfigs.ts b/examples/angular-cli-material/src/app/modal-gallery/libconfigs.ts new file mode 100644 index 00000000..fdf8c729 --- /dev/null +++ b/examples/angular-cli-material/src/app/modal-gallery/libconfigs.ts @@ -0,0 +1,583 @@ +import { + ButtonsStrategy, + ButtonType, + Description, + DescriptionStrategy, + KS_DEFAULT_BTN_CLOSE, + KS_DEFAULT_BTN_DELETE, + KS_DEFAULT_BTN_DOWNLOAD, + KS_DEFAULT_BTN_EXTURL, + KS_DEFAULT_BTN_FULL_SCREEN, + LoadingConfig, + LoadingType, + ModalLibConfig, + Size +} from '@ks89/angular-modal-gallery'; + +const DEFAULT_SIZE_PREVIEWS: Size = { + width: '100px', + height: 'auto' +}; + +// Examples A +export const LIBCONFIG_406: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: true, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +export const LIBCONFIG_407: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: false, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +export const LIBCONFIG_408: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: false, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +// Examples B +export const LIBCONFIG_500: ModalLibConfig = { + previewConfig: { + visible: false + }, + dotsConfig: { + visible: false + } +}; + +export const LIBCONFIG_501: ModalLibConfig = { + buttonsConfig: { + visible: false, + strategy: ButtonsStrategy.DEFAULT + }, + previewConfig: { + visible: false + }, + dotsConfig: { + visible: false + } +}; + +export const LIBCONFIG_502: ModalLibConfig = { + buttonsConfig: { + visible: false, + strategy: ButtonsStrategy.DEFAULT + }, + slideConfig: { + infinite: false, + sidePreviews: { + show: false, + size: DEFAULT_SIZE_PREVIEWS + } + }, + previewConfig: { + visible: false + }, + dotsConfig: { + visible: false + } +}; + +export const LIBCONFIG_503: ModalLibConfig = { + previewConfig: { + visible: true, + size: { + width: '90px', + height: 'auto' + } + } +}; + +export const LIBCONFIG_504: ModalLibConfig = { + enableCloseOutside: false +}; + +export const LIBCONFIG_505: ModalLibConfig = { + currentImageConfig: { downloadable: false }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.DEFAULT + } +}; + +export const LIBCONFIG_506: ModalLibConfig = { + currentImageConfig: { downloadable: true }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.DEFAULT + } +}; + +export const LIBCONFIG_507: ModalLibConfig = { + currentImageConfig: { downloadable: true }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.SIMPLE + } +}; + +export const LIBCONFIG_508: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: false, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +export const LIBCONFIG_509: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: true, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +export const LIBCONFIG_510: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: false, + type: LoadingType.STANDARD + } + } +}; +export const LIBCONFIG_511: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.STANDARD + } + } +}; +export const LIBCONFIG_512: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.CIRCULAR + } + } +}; +export const LIBCONFIG_513: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.BARS + } + } +}; +export const LIBCONFIG_514: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.DOTS + } + } +}; +export const LIBCONFIG_515: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.CUBE_FLIPPING + } + } +}; +export const LIBCONFIG_516: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.CIRCLES + } + } +}; +export const LIBCONFIG_517: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.EXPLOSING_SQUARES + } + } +}; + +export const LIBCONFIG_518: ModalLibConfig = { + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.DEFAULT + } +}; +export const LIBCONFIG_519: ModalLibConfig = { + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.SIMPLE + } +}; +export const LIBCONFIG_520: ModalLibConfig = { + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.ADVANCED + } +}; +export const LIBCONFIG_521: ModalLibConfig = { + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.FULL + } +}; + +// default buttons but extUrl will open the link in a new tab instead of the current one +// this requires to specify all buttons manually (also if they are not really custom) +export const LIBCONFIG_522: ModalLibConfig = { + currentImageConfig: { downloadable: true }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.CUSTOM, + buttons: [ + { + className: 'ext-url-image', + type: ButtonType.EXTURL, + extUrlInNewTab: true // <--- this is the important thing to understand this example + }, + { + className: 'download-image', + type: ButtonType.DOWNLOAD + }, + { + className: 'close-image', + type: ButtonType.CLOSE + } + ] + } +}; + +export const LIBCONFIG_523: ModalLibConfig = { + currentImageConfig: { + downloadable: true + }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.CUSTOM, + buttons: [ + // KS_DEFAULT_BTN_ROTATE, + KS_DEFAULT_BTN_FULL_SCREEN, + KS_DEFAULT_BTN_DELETE, + KS_DEFAULT_BTN_EXTURL, + KS_DEFAULT_BTN_DOWNLOAD, + KS_DEFAULT_BTN_CLOSE + ] + } +}; + +export const LIBCONFIG_524: ModalLibConfig = { + currentImageConfig: { + downloadable: true + }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.CUSTOM, + buttons: [ + { + className: 'fas fa-plus white', + type: ButtonType.CUSTOM, + ariaLabel: 'custom plus aria label', + title: 'custom plus title', + fontSize: '20px' + }, + { + className: 'fas fa-times white', + type: ButtonType.CLOSE, + ariaLabel: 'custom close aria label', + title: 'custom close title', + fontSize: '20px' + }, + { + className: 'fas fa-download white', + type: ButtonType.DOWNLOAD, + ariaLabel: 'custom download aria label', + title: 'custom download title', + fontSize: '20px' + }, + { + className: 'fas fa-external-link-alt white', + type: ButtonType.EXTURL, + ariaLabel: 'custom exturl aria label', + title: 'custom exturl title', + fontSize: '20px' + } + ] + } +}; + +export const LIBCONFIG_525: ModalLibConfig = { + previewConfig: { + visible: true, + mobileVisible: true + } +}; + +// Examples C +export const LIBCONFIG_600: ModalLibConfig = { + keyboardConfig: { + esc: 'KeyQ', + left: 'ArrowDown', + right: 'ArrowUp' + } +}; + +export const LIBCONFIG_601: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + imageText: 'Look this image ', + numberSeparator: ' of ', + beforeTextDescription: ' => ' + } + } +}; + +export const LIBCONFIG_602: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.HIDE_IF_EMPTY, + imageText: 'Look this image ', + numberSeparator: ' of ', + beforeTextDescription: ' => ' + } + } +}; + +export const LIBCONFIG_603: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_HIDDEN, + // you should build this value programmatically with the result of (show)="..()" event + customFullDescription: 'Custom description of the current visible image' + // if customFullDescription !== undefined, all other fields will be ignored + // imageText: '', + // numberSeparator: '', + // beforeTextDescription: '', + } + } +}; + +export const LIBCONFIG_604: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + // you should build this value programmatically with the result of (show)="..()" event + customFullDescription: 'Custom description of the current visible image' + // if customFullDescription !== undefined, all other fields will be ignored + // imageText: '', + // numberSeparator: '', + // beforeTextDescription: '', + } + } +}; + +export const LIBCONFIG_605: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + imageText: 'Look this image ', + numberSeparator: ' of ', + beforeTextDescription: ' => ' + } + } +}; + +export const LIBCONFIG_606: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + imageText: 'Look this image ', + numberSeparator: ' of ', + beforeTextDescription: ' => ', + style: { + bgColor: 'rgba(255,0,0,.5)', + textColor: 'blue', + marginTop: '3px', + marginBottom: '0px', + marginLeft: '5px', + marginRight: '5px', + position: 'absolute', + top: '0px', + height: '25px' + // be careful to use width, in particular with % values + } + } + } +}; + +export const LIBCONFIG_607: ModalLibConfig = { + previewConfig: { + visible: true, + number: 1 + } +}; + +export const LIBCONFIG_608: ModalLibConfig = { + previewConfig: { + visible: true, + number: 5 + } +}; + +export const LIBCONFIG_609: ModalLibConfig = { + previewConfig: { + visible: true, + arrows: false + } +}; + +export const LIBCONFIG_610: ModalLibConfig = { + previewConfig: { + visible: true, + clickable: false + } +}; + +export const LIBCONFIG_611: ModalLibConfig = { + previewConfig: { + visible: true, + size: { width: '30px', height: '30px' } + } +}; + +export const LIBCONFIG_612: ModalLibConfig = { + accessibilityConfig: { + backgroundAriaLabel: 'CUSTOM Modal gallery full screen background', + backgroundTitle: 'CUSTOM background title', + + plainGalleryContentAriaLabel: 'CUSTOM Plain gallery content', + plainGalleryContentTitle: 'CUSTOM plain gallery content title', + + modalGalleryContentAriaLabel: 'CUSTOM Modal gallery content', + modalGalleryContentTitle: 'CUSTOM modal gallery content title', + + loadingSpinnerAriaLabel: 'CUSTOM The current image is loading. Please be patient.', + loadingSpinnerTitle: 'CUSTOM The current image is loading. Please be patient.', + + mainContainerAriaLabel: 'CUSTOM Current image and navigation', + mainContainerTitle: 'CUSTOM main container title', + mainPrevImageAriaLabel: 'CUSTOM Previous image', + mainPrevImageTitle: 'CUSTOM Previous image', + mainNextImageAriaLabel: 'CUSTOM Next image', + mainNextImageTitle: 'CUSTOM Next image', + + dotsContainerAriaLabel: 'CUSTOM Image navigation dots', + dotsContainerTitle: 'CUSTOM dots container title', + dotAriaLabel: 'CUSTOM Navigate to image number', + + previewsContainerAriaLabel: 'CUSTOM Image previews', + previewsContainerTitle: 'CUSTOM previews title', + previewScrollPrevAriaLabel: 'CUSTOM Scroll previous previews', + previewScrollPrevTitle: 'CUSTOM Scroll previous previews', + previewScrollNextAriaLabel: 'CUSTOM Scroll next previews', + previewScrollNextTitle: 'CUSTOM Scroll next previews', + + carouselContainerAriaLabel: 'Current image and navigation', + carouselContainerTitle: '', + carouselPrevImageAriaLabel: 'Previous image', + carouselPrevImageTitle: 'Previous image', + carouselNextImageAriaLabel: 'Next image', + carouselNextImageTitle: 'Next image', + carouselPreviewsContainerAriaLabel: 'Image previews', + carouselPreviewsContainerTitle: '', + carouselPreviewScrollPrevAriaLabel: 'Scroll previous previews', + carouselPreviewScrollPrevTitle: 'Scroll previous previews', + carouselPreviewScrollNextAriaLabel: 'Scroll next previews', + carouselPreviewScrollNextTitle: 'Scroll next previews' + } +}; + +export const LIBCONFIG_613: ModalLibConfig = { + currentImageConfig: { + navigateOnClick: false + } +}; + +// Examples D +export const LIBCONFIG_701: ModalLibConfig = { + currentImageConfig: { + downloadable: true + }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.SIMPLE + } +}; + +export const LIBCONFIG_702: ModalLibConfig = { + currentImageConfig: { + invertSwipe: true + } +}; + +export const LIBCONFIG_703: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: true, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +// Examples E +export const LIBCONFIG_800: ModalLibConfig = { + slideConfig: { + playConfig: { + autoPlay: true, + interval: 5000, + pauseOnHover: true + } + } +}; + +export const LIBCONFIG_801: ModalLibConfig = { + slideConfig: { + infinite: true, + playConfig: { + autoPlay: true, + interval: 5000, + pauseOnHover: false + } + } +}; + +export const LIBCONFIG_802: ModalLibConfig = { + slideConfig: { + playConfig: { + autoPlay: true, + interval: 1000, + pauseOnHover: false + } + } +}; + +// Examples F +export const LIBCONFIG_900: ModalLibConfig = { + slideConfig: { + infinite: false + }, + currentImageConfig: { + loadingConfig: { enable: true, type: LoadingType.STANDARD } as LoadingConfig, + description: { strategy: DescriptionStrategy.ALWAYS_VISIBLE } as Description + } +}; diff --git a/examples/angular-cli-material/src/app/modal-gallery/modal-gallery.component.ts b/examples/angular-cli-material/src/app/modal-gallery/modal-gallery.component.ts new file mode 100644 index 00000000..303d2977 --- /dev/null +++ b/examples/angular-cli-material/src/app/modal-gallery/modal-gallery.component.ts @@ -0,0 +1,763 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { TemplateRef } from '@angular/core'; +import { ViewChild } from '@angular/core'; +import { Component, OnDestroy } from '@angular/core'; +import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; + +import { + Action, + ButtonEvent, + ButtonType, + Image, + ImageModalEvent, + ModalGalleryService, + ModalGalleryRef, + ModalGalleryConfig, + ModalLibConfig +} from '@ks89/angular-modal-gallery'; +import { Subscription } from 'rxjs'; + +import * as libConfigs from './libconfigs'; + +@Component({ + selector: 'ks-modal-gallery-page', + templateUrl: './modal-gallery.html', + styleUrls: ['./modal-gallery.scss'], + standalone: false +}) +export class ModalGalleryExampleComponent implements OnDestroy { + /** + * A custom template to illustrate the customization of previews rendering. + */ + @ViewChild('previewsTemplate') + previewsTemplate?: TemplateRef; + + imageIndex = 0; + galleryId = 1; + isPlaying = true; + // Examples A + CONFIG406: ModalLibConfig = libConfigs.LIBCONFIG_406; + CONFIG407: ModalLibConfig = libConfigs.LIBCONFIG_407; + CONFIG408: ModalLibConfig = libConfigs.LIBCONFIG_408; + // Examples B + CONFIG500: ModalLibConfig = libConfigs.LIBCONFIG_500; + CONFIG501: ModalLibConfig = libConfigs.LIBCONFIG_501; + CONFIG502: ModalLibConfig = libConfigs.LIBCONFIG_502; + CONFIG503: ModalLibConfig = libConfigs.LIBCONFIG_503; + CONFIG504: ModalLibConfig = libConfigs.LIBCONFIG_504; + CONFIG505: ModalLibConfig = libConfigs.LIBCONFIG_505; + CONFIG506: ModalLibConfig = libConfigs.LIBCONFIG_506; + CONFIG507: ModalLibConfig = libConfigs.LIBCONFIG_507; + CONFIG508: ModalLibConfig = libConfigs.LIBCONFIG_508; + CONFIG509: ModalLibConfig = libConfigs.LIBCONFIG_509; + CONFIG510: ModalLibConfig = libConfigs.LIBCONFIG_510; + CONFIG511: ModalLibConfig = libConfigs.LIBCONFIG_511; + CONFIG512: ModalLibConfig = libConfigs.LIBCONFIG_512; + CONFIG513: ModalLibConfig = libConfigs.LIBCONFIG_513; + CONFIG514: ModalLibConfig = libConfigs.LIBCONFIG_514; + CONFIG515: ModalLibConfig = libConfigs.LIBCONFIG_515; + CONFIG516: ModalLibConfig = libConfigs.LIBCONFIG_516; + CONFIG517: ModalLibConfig = libConfigs.LIBCONFIG_517; + CONFIG518: ModalLibConfig = libConfigs.LIBCONFIG_518; + CONFIG519: ModalLibConfig = libConfigs.LIBCONFIG_519; + CONFIG520: ModalLibConfig = libConfigs.LIBCONFIG_520; + CONFIG521: ModalLibConfig = libConfigs.LIBCONFIG_521; + CONFIG522: ModalLibConfig = libConfigs.LIBCONFIG_522; + CONFIG523: ModalLibConfig = libConfigs.LIBCONFIG_523; + CONFIG524: ModalLibConfig = libConfigs.LIBCONFIG_524; + CONFIG525: ModalLibConfig = libConfigs.LIBCONFIG_525; + // Examples C + CONFIG600: ModalLibConfig = libConfigs.LIBCONFIG_600; + CONFIG601: ModalLibConfig = libConfigs.LIBCONFIG_601; + CONFIG602: ModalLibConfig = libConfigs.LIBCONFIG_602; + CONFIG603: ModalLibConfig = libConfigs.LIBCONFIG_603; + CONFIG604: ModalLibConfig = libConfigs.LIBCONFIG_604; + CONFIG605: ModalLibConfig = libConfigs.LIBCONFIG_605; + CONFIG606: ModalLibConfig = libConfigs.LIBCONFIG_606; + CONFIG607: ModalLibConfig = libConfigs.LIBCONFIG_607; + CONFIG608: ModalLibConfig = libConfigs.LIBCONFIG_608; + CONFIG609: ModalLibConfig = libConfigs.LIBCONFIG_609; + CONFIG610: ModalLibConfig = libConfigs.LIBCONFIG_610; + CONFIG611: ModalLibConfig = libConfigs.LIBCONFIG_611; + CONFIG612: ModalLibConfig = libConfigs.LIBCONFIG_612; + CONFIG613: ModalLibConfig = libConfigs.LIBCONFIG_613; + // Examples D + CONFIG701: ModalLibConfig = libConfigs.LIBCONFIG_701; + CONFIG702: ModalLibConfig = libConfigs.LIBCONFIG_702; + CONFIG703: ModalLibConfig = libConfigs.LIBCONFIG_703; + // Examples E + CONFIG800: ModalLibConfig = libConfigs.LIBCONFIG_800; + CONFIG801: ModalLibConfig = libConfigs.LIBCONFIG_801; + CONFIG802: ModalLibConfig = libConfigs.LIBCONFIG_802; + // Example F + CONFIG900: ModalLibConfig = libConfigs.LIBCONFIG_900; + + images: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: '../assets/images/gallery/img2.jpg', + description: 'Description 2' + }), + new Image( + 2, + { + img: '../assets/images/gallery/img3.jpg', + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new Image(3, { + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new Image(4, { img: '../assets/images/gallery/img5.jpg' }, { img: '../assets/images/gallery/thumbs/img5.jpg' }) + ]; + + emptyImagesArray: Image[] = []; + + imagesRectNoTitles: Image[] = [ + new Image( + 0, + { img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', title: '' } + ), + new Image( + 1, + { img: '../assets/images/gallery/pexels-photo-47223.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg', title: '' } + ), + new Image( + 2, + { img: '../assets/images/gallery/pexels-photo-52062.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', title: '' } + ), + new Image( + 3, + { img: '../assets/images/gallery/pexels-photo-66943.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', title: '' } + ), + new Image( + 4, + { img: '../assets/images/gallery/pexels-photo-93750.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg', title: '' } + ), + new Image( + 5, + { img: '../assets/images/gallery/pexels-photo-94420.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg', title: '' } + ), + new Image( + 6, + { img: '../assets/images/gallery/pexels-photo-96947.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg', title: '' } + ) + ]; + + fallbackImages: Image[] = [ + new Image(0, { + // this file is not available so the browser returns an error + img: '../assets/images/gallery/UNEXISTING_IMG1.jpg', + // because the img above doesn't exists, the library will use this file + fallbackImg: '../assets/images/gallery/fallback1.jpg' + }), + new Image(1, { + img: '../assets/images/gallery/UNEXISTING_IMG2.jpg', + fallbackImg: '../assets/images/gallery/fallback2.jpg' + }), + new Image( + 2, + { + img: '../assets/images/gallery/UNEXISTING_IMG3.jpg', + fallbackImg: '../assets/images/gallery/fallback3.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG3.png', + fallbackImg: '../assets/images/gallery/fallback3.jpg' + } + ), + new Image(3, { + img: '../assets/images/gallery/UNEXISTING_IMG4.jpg', + fallbackImg: '../assets/images/gallery/fallback4.jpg' + }), + new Image( + 4, + { + img: '../assets/images/gallery/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback5.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback5.jpg' + } + ) + ]; + + // array of images (obviously with different id) where paths are the same. + // to prevent caching issues I have to append '?index'. + sameImages: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg?1', + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: '../assets/images/gallery/img1.jpg?2', + extUrl: 'http://www.google.com' + }), + new Image(2, { + img: '../assets/images/gallery/img1.jpg?3', + extUrl: 'http://www.google.com' + }) + ]; + + // example of a png converted into base64 using https://www.base64-image.de/ or other similar websites + base64String = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABN0lEQV' + + 'R4nO3SQQ2AQBDAwAVlaMEhCkAV' + + 'b2RcQmcU9NEZAAAAAOD/tvN675k5VoewxLOvLmAtA8QZIM4AcQaIM0CcAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4gwQZ4A4A8QZIM4AcQaIM0C' + + 'cAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4gwQZ4A4A8QZIM4AcQaIM0CcAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4g' + + 'wQZ4A4A8QZIM4AcQaIM0CcAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4gwQZ4A4A8QZIM4AcQaIM0CcAeIMEGeAOAPEGQAAAAAA4Pc+8asEoPPGq' + + 'xUAAAAASUVORK5CYII'; + + base64RedString = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAY1BMVEX/AAD/////WVn/+vr/qan/Nzf/ERH/2tr/s7P/KSn/' + + '7+//vr7/0ND/W1v/6+v/m5v/4+P/U1P/HR3/o6P/rq7/g4P/k5P/t7f/dXX/SEj/zMz/ZWX/h4f/bm7/amr/np7/yMhDG/2oAAAC8ElEQVR4nO3dC3KqQBCF4WkHERHFRyKIL/' + + 'a/ymDuVYMMFipTbbfnW8H5S4lQVGUMaWe4B3iHQvlQKB8K5UOhfCiUD4XyoVA+FJ7Myijd5dvBO9nmuzQqZ68X2mI9NO9suC7s84VxNuAO6GSQxU8VJvuQe3pn4T55uLDYcK9+' + + '0KZ4qDB574vPbej+HF2Fcc499km563p0FAbcQ18QdCi0B+6VLzk0fjtuC0dj7o0vGo/uF064B/agvFcYca/rRdReeOTe1pNjW6HkP6J1gbtQwzV4NnEVJtyrepU0C2M599ldhH' + + 'GjcMq9qWfT28KUe1Hv0nrhnHuPB/Na4YJ7jgeLv4UZ9xovsmuhXXKP8WJpL4Ur7i2erC6Fun4Kr8Jz4Rf3Em++/hdKf+htN/5XqOuGtC75LfzmnuHR96nQ6v2SVl9TWxVq/pKevq' + + 'aG1twjvFpXhTLeLz1rQMZyb/DMmhH3BM9GRudjxVVmtN51n62M1DdpXeVG2rveR22MxLe9jxgazfdsJ2Oj9en3THsfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + + 'AAAAAAAAAAAAAAgHba/+98+AFnI+g/30L/GSX6z5nRf1aQ/vOe9J/Zpf/cNf1n533A+Yf6z7DUfw6p/rNkVX9Nkw850/kDzuXWf7Y6ab37Xl0K7ZJ7ixdLeykknQ8YGV0LacG9xo' + + 'MF/S2cc8/xYF4rpJR7T+9SqhfSlHtRz6Z0Wxjr+lEM40ahstvThJqFNOFe1aMJuQop4N7Vm4DchXTkXtaTI7UVUsS9rRcRtRequBZLuldII+mPw+MR3S8ke+De+JKDvQ1qFMr+kx' + + 'o0cxyFFEt945bHjhpXYXV/I/HN8DBxtrgLiQpp74Y3RUtJW2H1Oe7l3IuHe/fnd7+wuh4zGe+lBpnr+utSWLHF+r0vyeG6aPw+PFT4a1ZG6S7fDt7JNt+lUTnrsL5LoWwolA+F8q' + + 'FQPhTKh0L5UCgfCuVDoXw/lnQz7dm7GjoAAAAASUVORK5CYII='; + base64GreenString = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAgMAAADQNkYNAAAADFBMVEUAAAAy/ysy/ysy/ysyTcibAAAAA3RSTlMA2r/af0d' + + 'WAAAAQUlEQVRo3u3YMREAMAzEsJAMyZJsMXy3XORdBFySJK3qxFXH1Y1DEARBEARBEARBEARBEARBkNmk436mvSRJ0o4eOKL2P81eyn8AAAAASUVORK5CYII='; + + base64Image: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.base64String); + base64RedImage: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.base64RedString); + base64GreenImage: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.base64GreenString); + + imagesBase64: Image[] = [ + new Image(0, { + img: this.base64Image, + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: this.base64GreenImage, + description: 'Description 2' + }), + new Image( + 2, + { + img: this.base64RedImage, + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + img: this.base64RedImage, + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ) + ]; + + imagesCustomDownloadFileName: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg', + downloadFileName: 'first-img.jpg' + }), + new Image(1, { + img: this.base64Image, + downloadFileName: 'second-img-base64.jpg' + }) + ]; + + imagesHtmlDescriptions: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: '../assets/images/gallery/img2.jpg', + description: '
  1. This is
  2. the description
  3. number
  4. 2
' + }), + new Image( + 2, + { + img: '../assets/images/gallery/img3.jpg', + description: '
  • Description
  • 3
', + extUrl: 'http://www.google.com' + }, + { + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new Image(3, { + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new Image(4, { img: '../assets/images/gallery/img5.jpg' }, { img: '../assets/images/gallery/thumbs/img5.jpg' }) + ]; + + imagesRect: Image[] = [ + new Image( + 0, + { + img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1' + }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg' } + ), + new Image(1, { img: '../assets/images/gallery/pexels-photo-47223.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg' }), + new Image( + 2, + { + img: '../assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3' + }, + { + img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '../assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4' + }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg' } + ), + new Image(4, { img: '../assets/images/gallery/pexels-photo-93750.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg' }), + new Image( + 5, + { + img: '../assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6' + }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg' } + ), + new Image(6, { img: '../assets/images/gallery/pexels-photo-96947.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg' }) + ]; + + imagesMixedSizes: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/pexels-photo-135230.png', + description: 'Description 1' + }), + new Image(1, { + img: '../assets/images/gallery/pexels-photo-547115.jpeg' + }), + new Image(2, { + img: '../assets/images/gallery/pexels-photo-556664.jpeg', + description: 'Description 3' + }), + new Image(3, { + img: '../assets/images/gallery/pexels-photo-787594.jpeg', + description: 'Description 4' + }), + new Image(4, { + img: '../assets/images/gallery/pexels-photo-803105.jpeg' + }) + ]; + + // example of images with small previews (they are different files) to show + // loading spinners + imagesForLoadingSpinner: Image[] = [ + new Image( + 0, + { + img: '../assets/images/loading-spinner-samples/pexels-photo-74506.jpg' + }, + { img: '../assets/images/loading-spinner-samples/pexels-photo-74506-thumb.jpg' } + ), + new Image( + 1, + { + img: '../assets/images/loading-spinner-samples/pexels-photo-106006.jpg' + }, + { img: '../assets/images/loading-spinner-samples/pexels-photo-106006-thumb.jpg' } + ), + new Image( + 2, + { + img: '../assets/images/loading-spinner-samples/pexels-photo-464336.jpg' + }, + { img: '../assets/images/loading-spinner-samples/pexels-photo-464336-thumb.jpg' } + ), + new Image( + 3, + { + img: '../assets/images/loading-spinner-samples/pexels-photo.jpg' + }, + { img: '../assets/images/loading-spinner-samples/pexels-photo-thumb.jpg' } + ), + new Image( + 4, + { + img: '../assets/images/loading-spinner-samples/traffic-highway-lights-night-56891.jpg' + }, + { img: '../assets/images/loading-spinner-samples/traffic-highway-lights-night-56891-thumb.jpg' } + ) + ]; + + // array with a single image inside (the first one) + singleImage: Image[] = [this.images[0]]; + + imagesInfiniteAutoAdd: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg?1', + extUrl: 'http://www.google.com' + }) + ]; + + private count = 0; + + // subscriptions to receive events from the gallery + // REMEMBER TO call unsubscribe(); in ngOnDestroy (see below) + private closeSubscription: Subscription | undefined; + private showSubscription: Subscription | undefined; + private firstImageSubscription: Subscription | undefined; + private lastImageSubscription: Subscription | undefined; + private hasDataSubscription: Subscription | undefined; + private buttonBeforeHookSubscription: Subscription | undefined; + private buttonAfterHookSubscription: Subscription | undefined; + + constructor(private modalGalleryService: ModalGalleryService, private sanitizer: DomSanitizer) {} + + // this variable is used only for example of auto navigation + // tslint:disable-next-line:no-any + private timeout: any; + + openModalWithAutoClose(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + + this.showSubscription = dialogRef.show$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - show$: ', event); + const galleryId: number = event.galleryId; + console.log(`onShowAutoCloseExample with id=${galleryId} action: ` + Action[event.action]); + console.log('onShowAutoCloseExample result:' + event.result); + console.log('Starting timeout of 3 seconds to close modal gallery automatically'); + // clear previous timeout + clearTimeout(this.timeout); + this.timeout = setTimeout(() => { + console.log('setTimeout end - closing gallery with id=' + galleryId); + this.modalGalleryService.close(galleryId, false); + }, 3000); + }); + } + + addRandomImage(): void { + // add to images array + const imageToCopy: Image = this.images[Math.floor(Math.random() * this.images.length)]; + const newImage: Image = new Image(this.images.length - 1 + 1, imageToCopy.modal, imageToCopy.plain); + this.images = [...this.images, newImage]; + // add also to imagesRect + const imageRectToCopy: Image = this.imagesRect[Math.floor(Math.random() * this.imagesRect.length)]; + const newImageRect: Image = new Image(this.imagesRect.length - 1 + 1, imageRectToCopy.modal, imageRectToCopy.plain); + this.imagesRect = [...this.imagesRect, newImageRect]; + // add also to imagesMixedSizes + const imageMixToCopy: Image = this.imagesMixedSizes[Math.floor(Math.random() * this.imagesMixedSizes.length)]; + const newImageMix: Image = new Image(this.imagesMixedSizes.length - 1 + 1, imageMixToCopy.modal, imageMixToCopy.plain); + this.imagesMixedSizes = [...this.imagesMixedSizes, newImageMix]; + } + + openModal(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + if(imagesArrayToUse.length === 0) { + console.error('Cannot open modal-gallery because images array cannot be empty'); + return; + } + if(imageIndex > imagesArrayToUse.length - 1) { + console.error('Cannot open modal-gallery because imageIndex must be valid'); + return; + } + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + } + + openModalWithOutputs(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.closeSubscription = dialogRef.close$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - close$: ', event); + }); + this.showSubscription = dialogRef.show$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - show$: ', event); + }); + this.firstImageSubscription = dialogRef.firstImage$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - firstImage$: ', event); + }); + this.lastImageSubscription = dialogRef.lastImage$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - lastImage$: ', event); + }); + this.hasDataSubscription = dialogRef.hasData$.subscribe((event: ImageModalEvent) => { + // angular-modal-gallery will emit this event if it will load successfully input images + console.log('OUTPUT - hasData$: ', event); + }); + this.buttonBeforeHookSubscription = dialogRef.buttonBeforeHook$.subscribe((event: ButtonEvent) => { + console.log('OUTPUT - buttonBeforeHook$: ', event); + if (!event || !event.button) { + return; + } + // Invoked after a click on a button, but before that the related + // action is applied. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + if (event.button.type === ButtonType.DELETE) { + // remove the current image and reassign all other to the array of images + console.log('delete in app with images count ' + this.images.length); + this.images = this.images.filter((val: Image) => event.image && val.id !== event.image.id); + } + }); + this.buttonAfterHookSubscription = dialogRef.buttonAfterHook$.subscribe((event: ButtonEvent) => { + if (!event || !event.button) { + return; + } + // Invoked after both a click on a button and its related action. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + }); + } + + openModalWithDeleteButton(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: [...imagesArrayToUse], + currentImage: Object.assign({}, imageToShow), + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.buttonBeforeHookSubscription = dialogRef.buttonBeforeHook$.subscribe((event: ButtonEvent) => { + console.log('OUTPUT - buttonBeforeHook$:', event); + if (!event || !event.button) { + return; + } + // Invoked after a click on a button, but before that the related + // action is applied. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + }); + this.buttonAfterHookSubscription = dialogRef.buttonAfterHook$.subscribe((event: ButtonEvent) => { + console.log('OUTPUT - buttonAfterHook$:', event); + if (!event || !event.button) { + return; + } + if (event.button.type === ButtonType.DELETE) { + // remove the current image and reassign all other to the array of images + this.images = this.images.filter((val: Image) => event.image && val.id !== event.image.id); + this.modalGalleryService.updateModalImages(this.images); + } + // Invoked after both a click on a button and its related action. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + }); + } + + openModalWithAddButton(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.buttonBeforeHookSubscription = dialogRef.buttonBeforeHook$.subscribe((event: ButtonEvent) => { + if (!event || !event.button) { + return; + } + // Invoked after a click on a button, but before that the related + // action is applied. + + if (event.button.type === ButtonType.CUSTOM) { + console.log('adding a new random image at the end'); + this.addRandomImage(); + setTimeout(() => { + this.modalGalleryService.updateModalImages(this.images); + }, 0); + } + }); + this.buttonAfterHookSubscription = dialogRef.buttonAfterHook$.subscribe((event: ButtonEvent) => { + console.log('OUTPUT - buttonAfterHook$:', event); + if (!event || !event.button) { + return; + } + // Invoked after both a click on a button and its related action. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + }); + } + + openModalWithAutoAdd(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.showSubscription = dialogRef.show$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - show$: ', event); + if (this.count !== 0) { + return; + } + const interval = setInterval(() => { + const imageToCopy: Image = this.images[Math.floor(Math.random() * this.images.length)]; + const newImage: Image = new Image(this.imagesInfiniteAutoAdd.length - 1 + 1, imageToCopy.modal, imageToCopy.plain); + newImage.modal.img += `?${this.imagesInfiniteAutoAdd.length + 1}`; + this.imagesInfiniteAutoAdd = [...this.imagesInfiniteAutoAdd, newImage]; + this.modalGalleryService.updateModalImages(this.imagesInfiniteAutoAdd); + this.count++; + if (this.count === 4) { + clearInterval(interval); + } + }, 2000); + }); + } + + openModalWithAutoUpdate(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.showSubscription = dialogRef.show$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - show$: ', event); + if (this.count !== 0) { + return; + } + const indexToRefresh = 1; + const image: Image = new Image(1, { + img: '../assets/images/gallery/img5.jpg', + description: 'Description 2 updated with imag5.jpg' + }); + + console.log('updating image at index ' + indexToRefresh + ', after 4 seconds'); + + // create the new array of images with the updated image inside + const newImages: Image[] = [...this.images]; + newImages[indexToRefresh] = image; + + setTimeout(() => { + this.modalGalleryService.updateModalImages(newImages); + console.log('image updated successfully!'); + }, 4000); + }); + } + + autoPlayButton(config: ModalLibConfig): boolean { + this.isPlaying = !this.isPlaying; + if (config && config.slideConfig && config.slideConfig.playConfig) { + config.slideConfig.playConfig.autoPlay = this.isPlaying; + } + return this.isPlaying; + } + + trackById(index: number, item: Image): number { + return item.id; + } + + openModalWithPreviewsTemplate(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + if(imagesArrayToUse.length === 0) { + console.error('Cannot open modal-gallery because images array cannot be empty'); + return; + } + if(imageIndex > imagesArrayToUse.length - 1) { + console.error('Cannot open modal-gallery because imageIndex must be valid'); + return; + } + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig, + previewsTemplate: this.previewsTemplate, + } as ModalGalleryConfig) as ModalGalleryRef; + } + + ngOnDestroy(): void { + // release resources to prevent memory leaks and unexpected behaviours + if (this.closeSubscription) { + this.closeSubscription.unsubscribe(); + } + if (this.showSubscription) { + this.showSubscription.unsubscribe(); + } + if (this.firstImageSubscription) { + this.firstImageSubscription.unsubscribe(); + } + if (this.lastImageSubscription) { + this.lastImageSubscription.unsubscribe(); + } + if (this.hasDataSubscription) { + this.hasDataSubscription.unsubscribe(); + } + if (this.buttonBeforeHookSubscription) { + this.buttonBeforeHookSubscription.unsubscribe(); + } + if (this.buttonAfterHookSubscription) { + this.buttonAfterHookSubscription.unsubscribe(); + } + } +} diff --git a/examples/angular-cli-material/src/app/modal-gallery/modal-gallery.html b/examples/angular-cli-material/src/app/modal-gallery/modal-gallery.html new file mode 100644 index 00000000..2a264c8b --- /dev/null +++ b/examples/angular-cli-material/src/app/modal-gallery/modal-gallery.html @@ -0,0 +1,325 @@ +

Modal Gallery

+
+ +

If you want, you can add a random image to every example + +

+
+

Index to open:   

+
+
+

WARNING: remember to use always different ids across your application!!!

+
+
+
+

Minimal examples

+
+

A1 - (id=400) - Minimal demo - all defaults (images array)

+ +
+
+

A1bis - (id=401) - Minimal demo - all defaults with rect images (imagesRect array)

+ +
+
+

A1tris - (id=402) - Minimal demo - all defaults with images of different sizes (imagesMixedSizes array)

+ +
+
+

A2 - (id=403) - Minimal demo - listen for events

+

I added 'openModalWithOutputs()' public method to listen for events

+ +
+
+

A3 - (id=405) - Minimal demo - single image (singleImage array)

+ +
+
+

A4 - (id=406) - Minimal demo - single image with infinite sliding enabled (to fix issue #156)

+ +
+
+

A5 - (id=407) - Minimal demo - two images with infinite sliding enabled (to fix issue #156)

+ +
+
+

A6 - (id=408) - Minimal demo - three image with infinite sliding enabled (to fix issue #156)

+ +
+
+

A7 - (id=409) - Minimal demo - use fallback images when it's not possible to load normal images (to fix issue #194)

+ +
+
+
+
+

Simple examples

+
+

B1 - (id=500) - Simple demo - only current image and buttons (previews and dots are hidden)

+ +
+
+

B2 - (id=501) - Simple demo - only current image (buttons, previews and dots are hidden)

+ +
+
+

B3 - (id=502) - Simple demo - only current image (side previews, buttons, previews and dots are hidden)

+ +
+
+

B3bis - (id=503) - Simple demo - custom preview size

+ +
+
+

B4 - (id=504) - Simple demo - disable closeOutside

+ +
+
+

B5 - (id=505) - Simple demo - no downloadable at all

+ +
+
+

B6 - (id=506) - Simple demo - no download button (only with keyboard)

+ +
+
+

B7 - (id=507) - Simple demo - download with both button and keyboard

+ +
+
+

B8 - (id=508) - Simple demo - infinite sliding but NO side previews

+ +
+
+

B9 - (id=509) - Simple demo - infinite sliding and side previews

+ +
+
+

B10 - (id=510) - Simple demo - disable loading spinner

+ +
+
+

B11 - (id=511) - Simple demo - loading spinner of type Standard

+ +
+
+

B12 - (id=512) - Simple demo - loading spinner of type Circular

+ +
+
+

B13 - (id=513) - Simple demo - loading spinner of type Bars

+ +
+
+

B14 - (id=514) - Simple demo - loading spinner of type Dots

+ +
+
+

B15 - (id=515) - Simple demo - loading spinner of type Cube Flipping

+ +
+
+

B16 - (id=516) - Simple demo - loading spinner of type Circles

+ +
+
+

B17 - (id=517) - Simple demo - loading spinner of type Explosing Squares

+ +
+ +
+

B18 - (id=518) - Simple demo - buttons config DEFAULT strategy (only close)

+ +
+
+

B19 - (id=519) - Simple demo - buttons config SIMPLE strategy (close and download)

+ +
+
+

B20 - (id=520) - Simple demo - buttons config ADVANCED strategy (close, download and exturl in the current + tab)

+ +
+
+

B21 - (id=521) - Simple demo - buttons config FULL strategy (all buttons)

+

I added also 'openModalWithDeleteButton()' public method to support delete button

+ +
+
+

B22 - (id=522) - Simple demo - buttons config CUSTOM strategy with exturl in ANOTHER TAB ('_blank')

+ +
+
+

B23 - (id=523) - Simple demo - buttons config CUSTOM but with all default buttons already included in the library

+

I added also 'openModalWithDeleteButton()' public method to support delete button

+ +
+
+

B24 - (id=524) - Simple demo - buttons config CUSTOM strategy with Font Awesome 5

+

I added also 'openModalWithAddButton()' public method to support delete button

+
+ +
+
+

B25 - (id=525) - Previews visible on mobile screen

+

Added PreviewConfig.mobileVisible configuration param

+
+ +
+
+
+
+

Advanced examples

+
+

C1 - (id=600) - Advanced demo - custom keyboard ('up'/'down' arrows and 'q' to close)

+ +
+
+

C2 - (id=601) - Advanced demo - custom description always visible

+ +
+
+

C3 - (id=602) - Advanced demo - custom description hide if empty

+ +
+
+

C4 - (id=603) - Advanced demo - custom description always hidden

+ +
+
+

C5 - (id=604) - Advanced demo - custom FULL description always visible

+ +
+
+

C6 - (id=605) - Advanced demo - custom HTML description always visible

+ +
+
+

C7 - (id=606) - Advanced demo - custom description style (always visible)

+ +
+ +
+

C8 - (id=607) - Advanced demo - preview custom configuration with 1 image (clickable)

+ +
+ +
+

C9 - (id=608) - Advanced demo - preview custom configuration with 5 images (clickable)

+ +
+ +
+

C10 - (id=609) - Advanced demo - preview custom configuration without arrows (clickable)

+ +
+
+

C11 - (id=610) - Advanced demo - preview custom configuration not clickable

+ +
+
+

C12 - (id=611) - Advanced demo - preview custom configuration with custom size

+ +
+ +
+

C13 - (id=612) - Advanced demo - accessibility config

+ +
+ +
+

C14 - (id=613) - Advanced demo - disable clicks on current image in modal-image

+ +
+ +
+

C15 - (id=614) - Advanced demo - after 3 seconds it closes modal gallery automatically with galleryService close method

+

Attention: please check the console to understand what it's happening!

+

Timer will clear and restart every time you show another image!

+ +
+ +
+
+
+

Other examples

+
+

D1 - (id=700) - Other demo - base64 images

+ +
+ +
+

D2 - (id=701) - Other demo - custom file name, used when downloaded

+ +
+ +
+

D3 - (id=702) - Other demo - invert touchscreen swipe direction

+ +
+ +
+

D4 - (id=703) - Other demo - infinite sliding and automatic add of images when the gallery is visible

+ +
+ +
+

D5 - (id=704) - Other demo - automatic update of the second image (index=1) via gallery service (open the second image and wait some seconds to see the result)

+ +
+ +
+

D6 - (id=705) - Other demo - remove title attribute on images

+ +
+ +
+

D7 - (id=706) - Other demo - modal gallery with an empty images array

+ +
+ +
+
+
+

AutoPlay examples

+
+

E1 - (id=800) - AutoPlay demo - with interval=5000 and pauseOnHover enabled

+ +
+
+

E2 - (id=801) - AutoPlay demo - with interval=5000, pauseOnHover disabled and infinite is enabled

+ +
+
+

E3 - (id=802) - AutoPlay demo - with interval=1000 and pauseOnHover disabled

+

+ +
+ + +
+
+
+

Experimental examples*

+

* these will be either improved or removed in next versions

+
+

F1 - (id=900) - Experimental demo - infinite sliding with only one image to see if side arrows are hidden

+ +
+
+

F2 - (id=901) - Experimental demo - an array of Images with the same source file (different classes/ids and paths with appended '?imageIndex' to prevent caching issues)

+ +
+
+

F3 - (id=902) - Experimental demo - 'previews' rendering customization (via Angular templates)

+ +
+
{{preview?.modal?.description ?? ' '}}
+
+ +
+
+
+ +
+ diff --git a/examples/angular-cli-material/src/app/modal-gallery/modal-gallery.scss b/examples/angular-cli-material/src/app/modal-gallery/modal-gallery.scss new file mode 100644 index 00000000..994466cd --- /dev/null +++ b/examples/angular-cli-material/src/app/modal-gallery/modal-gallery.scss @@ -0,0 +1,177 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +:host { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + margin-left: 20px; + margin-right: 20px; +} + +$text-color: #fff; +$background: rgba(0, 0, 0, .7); + +button { + background-color: #0060b7; + color: white; + height: 25px; + width: auto; + border: 0; + border-radius: 5px; + cursor: pointer; + + &:hover { + background-color: #0086ff; + } +} + +.my-app-custom-plain-container-row { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + .my-app-custom-image-row { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-column { + align-items: center; + display: flex; + flex-direction: column; + justify-content: flex-start; + + .my-app-custom-image-column { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-with-desc { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + figure { + margin: 0; + position: relative; + + img { + max-width: 100%; + height: auto; + cursor: pointer; + } + + figcaption { + background: rgba(0, 0, 0, .5); + color: #fff; + font-size: 85%; + padding: 5px; + position: absolute; + bottom: 3px; + left: 0; + right: 0; + } + } + + .description { + font-weight: bold; + text-align: center; + } + + .my-app-custom-image-with-desc { + height: auto; + margin-right: 2px; + width: 200px; + align-self: start; + } +} + +.more { + background: $background; + cursor: pointer; + color: $text-color; + padding-top: 4px; + height: 46px; + position: absolute; + text-align: center; + width: 50px; +} + + +.transcluded { + color: white; + font-weight: 600; + font-size: 24px; + text-align: center; + position: absolute; + top: 50%; + width: 100%; + pointer-events: none; +} + +.title { + margin-top: 40px; +} + +.preview-block { + margin-right: 10px; +} +.preview-description { + color: #fff; + margin-bottom: 3px; +} +.preview-description, +.preview-default { + text-align: center; +} diff --git a/examples/angular-cli-material/src/app/navbar/navbar.component.ts b/examples/angular-cli-material/src/app/navbar/navbar.component.ts new file mode 100644 index 00000000..7708d11a --- /dev/null +++ b/examples/angular-cli-material/src/app/navbar/navbar.component.ts @@ -0,0 +1,63 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { Component } from '@angular/core'; +import { Router } from '@angular/router'; +import { BreakpointObserver } from '@angular/cdk/layout'; + +@Component({ + selector: 'ks-navbar', + templateUrl: 'navbar.html', + styleUrls: ['navbar.scss'], + standalone: false +}) +export class NavbarComponent { + navbarHeight = '56px'; + // path: string = PATH + '/assets/amg.svg'; + + collapsed = false; + + constructor(private router: Router, breakpointObserver: BreakpointObserver) { + breakpointObserver.observe(['(min-width: 990px)']).subscribe(result => { + if (result.matches) { + console.log('min width 990px'); + this.collapsed = false; + } + }); + } + + isNavItemActive(location: string): string { + return this.router.url.includes(location) ? 'active' : ''; + } + + onNavigateTo(path: string): void { + this.collapsed = false; + this.router.navigate([path]); + } + + onToggle(): void { + this.collapsed = !this.collapsed; + this.navbarHeight = this.collapsed ? '56px' : '150px'; + } +} diff --git a/examples/angular-cli-material/src/app/navbar/navbar.html b/examples/angular-cli-material/src/app/navbar/navbar.html new file mode 100644 index 00000000..f95de0c4 --- /dev/null +++ b/examples/angular-cli-material/src/app/navbar/navbar.html @@ -0,0 +1,68 @@ + + + + + diff --git a/examples/angular-cli-material/src/app/navbar/navbar.scss b/examples/angular-cli-material/src/app/navbar/navbar.scss new file mode 100644 index 00000000..f8580359 --- /dev/null +++ b/examples/angular-cli-material/src/app/navbar/navbar.scss @@ -0,0 +1,233 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +nav { + padding-top: 8px; + padding-bottom: 8px; + padding-left: 16px; + padding-right: 16px; +} + +ul { + margin-top: 0; + margin-bottom: 0; + padding-left: 0; +} + +nav.nav-expanded { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + background-color: #343A40; + padding-top: 8px; + padding-left: 16px; + padding-bottom: 8px; + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 10; + + > .navbar-hamburger { + display: none; + background-color: #343A40; + border-color: rgba(255, 255, 255, .1); + + @media screen and (max-width: 990px) { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + cursor: pointer; + padding-top: 4px; + padding-bottom: 4px; + padding-left: 12px; + padding-right: 12px; + } + } + + > .navbar-wrapper { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + + @media screen and (max-width: 990px) { + display: none; + } + + > .navbar-brand { + font-size: 16px; + color: #ffffff; + font-weight: 400; + margin-left: 8px; + margin-right: 8px; + cursor: pointer; + + > img { + border-radius: 3px + } + + &:hover { + color: #bdbdbd; + } + } + + > .navbar-nav { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + list-style: none; + + > .nav-item { + cursor: pointer; + color: #e2e2e2; + + > a.nav-link { + color: #b9b9b9; + font-size: 14px; + font-weight: 400; + margin-left: 8px; + margin-right: 8px; + + &:hover { + color: #E2E2E2; + } + } + } + } + } + + > #githubButtons { + margin-right: 30px; + @media only screen and (max-width: 1059px) { + display: none; + } + + > .github-badge { + margin-left: 8px; + } + } +} + + +// cexpanded on mobile devices after pressing the hamburger button +nav.nav-collapsed { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + flex-wrap: wrap; + background-color: #343A40; + padding-top: 8px; + padding-left: 16px; + padding-bottom: 8px; + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 10; + + > .navbar-hamburger { + display: none; + background-color: #343A40; + border-color: rgba(255, 255, 255, .1); + + @media screen and (max-width: 990px) { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + cursor: pointer; + padding-top: 4px; + padding-bottom: 4px; + padding-left: 12px; + padding-right: 12px; + } + } + + > .navbar-wrapper { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + margin-top: 8px; + width: 100%; + + > .navbar-brand { + font-size: 16px; + color: #ffffff; + font-weight: 400; + margin-left: 8px; + margin-right: 8px; + margin-top: 8px; + margin-bottom: 8px; + cursor: pointer; + width: 100%; + + > img { + border-radius: 3px + } + + &:hover { + color: #bdbdbd; + } + } + + > .navbar-nav { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + width: 100%; + list-style: none; + + > .nav-item { + cursor: pointer; + color: #e2e2e2; + width: 100%; + margin-top: 8px; + margin-bottom: 8px; + + > a.nav-link { + color: #b9b9b9; + font-size: 14px; + font-weight: 400; + margin-left: 8px; + margin-right: 8px; + + &:hover { + color: #E2E2E2; + } + } + } + } + } +} + + + diff --git a/examples/angular-cli-material/src/app/plain-gallery/plain-gallery.component.ts b/examples/angular-cli-material/src/app/plain-gallery/plain-gallery.component.ts new file mode 100644 index 00000000..d6136df5 --- /dev/null +++ b/examples/angular-cli-material/src/app/plain-gallery/plain-gallery.component.ts @@ -0,0 +1,297 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; + +import { + GridLayout, + Image, + LineLayout, + PlainGalleryConfig, + PlainGalleryStrategy, + ModalGalleryService, + ModalGalleryRef, + PlainLibConfig +} from '@ks89/angular-modal-gallery'; + +@Component({ + selector: 'ks-plain-gallery-page', + templateUrl: './plain-gallery.html', + styleUrls: ['./plain-gallery.scss'], + standalone: false +}) +export class PlainGalleryExampleComponent { + plainGalleryRow: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout({ width: '80px', height: '80px' }, { length: 2, wrap: true }, 'flex-start') + }; + plainGalleryRowSpaceAround: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout({ width: '50px', height: '50px' }, { length: 2, wrap: true }, 'space-around') + }; + plainGalleryRowATags: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout({ width: '95px', height: '63px' }, { length: 4, wrap: true }, 'flex-start'), + // when advanced is defined, additionalBackground: '50% 50%/cover' will be used by default. + // I added this here, to be more explicit. + advanced: { aTags: true, additionalBackground: '50% 50%/cover' } + }; + + plainGalleryColumn: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.COLUMN, + layout: new LineLayout({ width: '50px', height: '50px' }, { length: 3, wrap: true }, 'flex-start') + }; + + plainGalleryGrid: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.GRID, + layout: new GridLayout({ width: '80px', height: '80px' }, { length: 3, wrap: true }) + }; + + images: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: '../assets/images/gallery/img2.jpg', + description: 'Description 2' + }), + new Image( + 2, + { + img: '../assets/images/gallery/img3.jpg', + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new Image(3, { + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new Image(4, { img: '../assets/images/gallery/img5.jpg' }, { img: '../assets/images/gallery/thumbs/img5.jpg' }) + ]; + + emptyImagesArray: Image[] = []; + + fallbackImages: Image[] = [ + new Image(0, { + // this file is not available so the browser returns an error + img: '../assets/images/gallery/UNEXISTING_IMG1.jpg', + // because the img above doesn't exists, the library will use this file + fallbackImg: '../assets/images/gallery/fallback1.jpg' + }), + new Image(1, { + img: '../assets/images/gallery/UNEXISTING_IMG2.jpg', + fallbackImg: '../assets/images/gallery/fallback2.jpg' + }), + new Image( + 2, + { + img: '../assets/images/gallery/UNEXISTING_IMG3.jpg', + fallbackImg: '../assets/images/gallery/fallback3.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG3.png', + fallbackImg: '../assets/images/gallery/fallback3.jpg' + } + ), + new Image(3, { + img: '../assets/images/gallery/UNEXISTING_IMG4.jpg', + fallbackImg: '../assets/images/gallery/fallback4.jpg' + }), + new Image( + 4, + { + img: '../assets/images/gallery/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback5.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback5.jpg' + } + ) + ]; + + imagesRect: Image[] = [ + new Image( + 0, + { + img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1' + }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg' } + ), + new Image(1, { img: '../assets/images/gallery/pexels-photo-47223.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg' }), + new Image( + 2, + { + img: '../assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3' + }, + { + img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '../assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4' + }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg' } + ), + new Image(4, { img: '../assets/images/gallery/pexels-photo-93750.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg' }), + new Image( + 5, + { + img: '../assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6' + }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg' } + ), + new Image(6, { img: '../assets/images/gallery/pexels-photo-96947.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg' }) + ]; + + imagesRectNoTitles: Image[] = [ + new Image( + 0, + { img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', title: '' } + ), + new Image( + 1, + { img: '../assets/images/gallery/pexels-photo-47223.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg', title: '' } + ), + new Image( + 2, + { img: '../assets/images/gallery/pexels-photo-52062.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', title: '' } + ), + new Image( + 3, + { img: '../assets/images/gallery/pexels-photo-66943.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', title: '' } + ), + new Image( + 4, + { img: '../assets/images/gallery/pexels-photo-93750.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg', title: '' } + ), + new Image( + 5, + { img: '../assets/images/gallery/pexels-photo-94420.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg', title: '' } + ), + new Image( + 6, + { img: '../assets/images/gallery/pexels-photo-96947.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg', title: '' } + ) + ]; + + libConfigPlainGalleryRow: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryRow + }; + libConfigPlainGalleryRowSpaceAround: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryRowSpaceAround + }; + libConfigPlainGalleryRowATags: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryRowATags + }; + libConfigPlainGalleryColumn: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryColumn + }; + libConfigPlainGalleryGrid: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryGrid + }; + + constructor(private modalGalleryService: ModalGalleryService, private sanitizer: DomSanitizer) {} + + openImageModalRow(id: number, image: Image): void { + console.log('Opening modal gallery from custom plain gallery row, with image: ', image); + const index: number = this.getCurrentIndexCustomLayout(image, this.images); + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: this.images, + currentImage: this.images[index] + }) as ModalGalleryRef; + } + + openImageModalColumn(id: number, image: Image): void { + console.log('Opening modal gallery from custom plain gallery column, with image: ', image); + const index: number = this.getCurrentIndexCustomLayout(image, this.images); + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: this.images, + currentImage: this.images[index] + }) as ModalGalleryRef; + } + + openImageModalRowDescription(id: number, image: Image): void { + console.log('Opening modal gallery from custom plain gallery row and description, with image: ', image); + const index: number = this.getCurrentIndexCustomLayout(image, this.imagesRect); + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: this.imagesRect, + currentImage: this.imagesRect[index] + }) as ModalGalleryRef; + } + + addRandomImage(): void { + // add to images array + const imageToCopy: Image = this.images[Math.floor(Math.random() * this.images.length)]; + const newImage: Image = new Image(this.images.length - 1 + 1, imageToCopy.modal, imageToCopy.plain); + this.images = [...this.images, newImage]; + // add also to imagesRect + const imageRectToCopy: Image = this.imagesRect[Math.floor(Math.random() * this.imagesRect.length)]; + const newImageRect: Image = new Image(this.imagesRect.length - 1 + 1, imageRectToCopy.modal, imageRectToCopy.plain); + this.imagesRect = [...this.imagesRect, newImageRect]; + } + + onShow(id: number, index: number, images: Image[] = this.images): void { + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images, + currentImage: images[index] + }) as ModalGalleryRef; + } + + trackById(index: number, item: Image): number { + return item.id; + } + + private getCurrentIndexCustomLayout(image: Image, images: Image[]): number { + return image ? images.indexOf(image) : -1; + } +} diff --git a/examples/angular-cli-material/src/app/plain-gallery/plain-gallery.html b/examples/angular-cli-material/src/app/plain-gallery/plain-gallery.html new file mode 100644 index 00000000..73f06879 --- /dev/null +++ b/examples/angular-cli-material/src/app/plain-gallery/plain-gallery.html @@ -0,0 +1,152 @@ +

Plain Gallery

+
+ +

If you want, you can add a random image to every example + +

+
+
+

Layout examples

+
+

P1 - (id=200) - row plain gallery layout (limit 2) and custom size

+
+ +
+
+
+

P2 - (id=201) - row plain gallery layout space around (limit 2)

+
+ +
+
+
+

P3 - (id=202) - row plain gallery layout with a tags and custom rectangular sizes (limit 4)

+
+ +
+
+
+

P4 - (id=203) - column plain gallery layout (limit 3)

+
+ +
+
+
+

P5 - (id=204) - grid plain gallery layout and custom size

+
+ +
+
+
+

P6 - (id=205) - full custom plain gallery (row) with image pointer

+
+
+ + + +
+
+
+
+

P7 - (id=206) - full custom plain gallery (column) with image pointer

+
+
+ + + +
+
+
+
+

P8 - (id=207) - full custom plain gallery (row) with descriptions

+
+
+ +
+ +
{{img.modal.description ? img.modal.description : 'No description available'}} +
+
+
+
+
+
+
+

P9 - (id=208) - row plain gallery layout with fallback images when it's not possible to load normal images (to fix issue #194)

+
+ +
+
+
+

P10 - (id=209) - row plain gallery layout with a tags and custom rectangular sizes (limit 4) + fallback images when it's not possible to load normal images (to fix issue #194)

+
+ +
+
+
+

P11 - (id=210) - row plain gallery layout (limit 2) and custom size + remove title attribute on images

+
+ +
+
+
+

P12 - (id=211) - row plain gallery layout with an empty images array

+
+ +
+
+
diff --git a/examples/angular-cli-material/src/app/plain-gallery/plain-gallery.scss b/examples/angular-cli-material/src/app/plain-gallery/plain-gallery.scss new file mode 100644 index 00000000..b498df8d --- /dev/null +++ b/examples/angular-cli-material/src/app/plain-gallery/plain-gallery.scss @@ -0,0 +1,169 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +:host { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + margin-left: 20px; + margin-right: 20px; +} + +section { + width: 100%; +} + +$text-color: #fff; +$background: rgba(0, 0, 0, .7); + +button { + background-color: #0060b7; + color: white; + height: 25px; + width: auto; + border: 0; + border-radius: 5px; + cursor: pointer; + + &:hover { + background-color: #0086ff; + } +} + +.my-app-custom-plain-container-row { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + .my-app-custom-image-row { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-column { + align-items: center; + display: flex; + flex-direction: column; + justify-content: flex-start; + + .my-app-custom-image-column { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-with-desc { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + figure { + margin: 0; + position: relative; + + img { + max-width: 100%; + height: auto; + cursor: pointer; + } + + figcaption { + background: rgba(0, 0, 0, .5); + color: #fff; + font-size: 85%; + padding: 5px; + position: absolute; + bottom: 3px; + left: 0; + right: 0; + } + } + + .description { + font-weight: bold; + text-align: center; + } + + .my-app-custom-image-with-desc { + height: auto; + margin-right: 2px; + width: 200px; + align-self: start; + } +} + +.more { + background: $background; + cursor: pointer; + color: $text-color; + padding-top: 4px; + height: 46px; + position: absolute; + text-align: center; + width: 50px; +} + + +.transcluded { + color: white; + font-weight: 600; + font-size: 24px; + text-align: center; + position: absolute; + top: 50%; + width: 100%; + pointer-events: none; +} + +.title { + margin-top: 40px; +} diff --git a/examples/angular-cli-material/src/assets/images/gallery/fallback-carousel1.jpg b/examples/angular-cli-material/src/assets/images/gallery/fallback-carousel1.jpg new file mode 100644 index 00000000..5d49263f Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/fallback-carousel1.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/fallback-carousel2.jpg b/examples/angular-cli-material/src/assets/images/gallery/fallback-carousel2.jpg new file mode 100644 index 00000000..2c2ce26a Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/fallback-carousel2.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/fallback-carousel3.jpg b/examples/angular-cli-material/src/assets/images/gallery/fallback-carousel3.jpg new file mode 100644 index 00000000..a4ea6b40 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/fallback-carousel3.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/fallback-carousel4.jpg b/examples/angular-cli-material/src/assets/images/gallery/fallback-carousel4.jpg new file mode 100644 index 00000000..0d59507d Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/fallback-carousel4.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/fallback-carousel5.jpg b/examples/angular-cli-material/src/assets/images/gallery/fallback-carousel5.jpg new file mode 100644 index 00000000..5511feb8 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/fallback-carousel5.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/fallback1.jpg b/examples/angular-cli-material/src/assets/images/gallery/fallback1.jpg new file mode 100644 index 00000000..0827c782 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/fallback1.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/fallback2.jpg b/examples/angular-cli-material/src/assets/images/gallery/fallback2.jpg new file mode 100644 index 00000000..6562c517 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/fallback2.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/fallback3.jpg b/examples/angular-cli-material/src/assets/images/gallery/fallback3.jpg new file mode 100644 index 00000000..3a3d63f4 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/fallback3.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/fallback4.jpg b/examples/angular-cli-material/src/assets/images/gallery/fallback4.jpg new file mode 100644 index 00000000..0dfe8551 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/fallback4.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/fallback5.jpg b/examples/angular-cli-material/src/assets/images/gallery/fallback5.jpg new file mode 100644 index 00000000..38da58e4 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/fallback5.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/img1.jpg b/examples/angular-cli-material/src/assets/images/gallery/img1.jpg new file mode 100644 index 00000000..7d358899 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/img1.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/img2.jpg b/examples/angular-cli-material/src/assets/images/gallery/img2.jpg new file mode 100644 index 00000000..4c101c12 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/img2.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/img2.png b/examples/angular-cli-material/src/assets/images/gallery/img2.png new file mode 100644 index 00000000..295cb1f4 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/img2.png differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/img3.jpg b/examples/angular-cli-material/src/assets/images/gallery/img3.jpg new file mode 100644 index 00000000..c6b1c22d Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/img3.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/img4.jpg b/examples/angular-cli-material/src/assets/images/gallery/img4.jpg new file mode 100644 index 00000000..403482ae Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/img4.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/img5.jpg b/examples/angular-cli-material/src/assets/images/gallery/img5.jpg new file mode 100644 index 00000000..bf97ab6c Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/img5.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/milan-pegasus-gallery-statue-1024w.jpg b/examples/angular-cli-material/src/assets/images/gallery/milan-pegasus-gallery-statue-1024w.jpg new file mode 100644 index 00000000..c0a922d1 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/milan-pegasus-gallery-statue-1024w.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/milan-pegasus-gallery-statue-480w.jpg b/examples/angular-cli-material/src/assets/images/gallery/milan-pegasus-gallery-statue-480w.jpg new file mode 100644 index 00000000..ac54d7d7 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/milan-pegasus-gallery-statue-480w.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/milan-pegasus-gallery-statue-768w.jpg b/examples/angular-cli-material/src/assets/images/gallery/milan-pegasus-gallery-statue-768w.jpg new file mode 100644 index 00000000..dba50163 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/milan-pegasus-gallery-statue-768w.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/milan-pegasus-gallery-statue.jpg b/examples/angular-cli-material/src/assets/images/gallery/milan-pegasus-gallery-statue.jpg new file mode 100644 index 00000000..f2c02760 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/milan-pegasus-gallery-statue.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-135230-1024w.png b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-135230-1024w.png new file mode 100644 index 00000000..a543d4db Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-135230-1024w.png differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-135230-480w.png b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-135230-480w.png new file mode 100644 index 00000000..dc29041e Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-135230-480w.png differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-135230-768w.png b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-135230-768w.png new file mode 100644 index 00000000..b04917ed Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-135230-768w.png differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-135230.png b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-135230.png new file mode 100644 index 00000000..8aa887fd Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-135230.png differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-47223-1024w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-47223-1024w.jpeg new file mode 100644 index 00000000..f7931c21 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-47223-1024w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-47223-480w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-47223-480w.jpeg new file mode 100644 index 00000000..14897ecf Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-47223-480w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-47223-768w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-47223-768w.jpeg new file mode 100644 index 00000000..73f72c9a Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-47223-768w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-47223.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-47223.jpeg new file mode 100644 index 00000000..46ea1f75 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-47223.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-52062-1024w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-52062-1024w.jpeg new file mode 100644 index 00000000..a7052fd3 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-52062-1024w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-52062-480w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-52062-480w.jpeg new file mode 100644 index 00000000..1ac7ce8c Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-52062-480w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-52062-768w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-52062-768w.jpeg new file mode 100644 index 00000000..e1f3256c Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-52062-768w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-52062.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-52062.jpeg new file mode 100644 index 00000000..0c9502e4 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-52062.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-547115-1024w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-547115-1024w.jpeg new file mode 100644 index 00000000..592a1516 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-547115-1024w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-547115-480w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-547115-480w.jpeg new file mode 100644 index 00000000..15c404dd Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-547115-480w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-547115-768w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-547115-768w.jpeg new file mode 100644 index 00000000..68fa15da Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-547115-768w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-547115.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-547115.jpeg new file mode 100644 index 00000000..4056b197 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-547115.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-556664-1024w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-556664-1024w.jpeg new file mode 100644 index 00000000..b56cf006 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-556664-1024w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-556664-480w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-556664-480w.jpeg new file mode 100644 index 00000000..f7990e34 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-556664-480w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-556664-768w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-556664-768w.jpeg new file mode 100644 index 00000000..cbb74582 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-556664-768w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-556664.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-556664.jpeg new file mode 100644 index 00000000..33383d36 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-556664.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-66943-1024w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-66943-1024w.jpeg new file mode 100644 index 00000000..18988bf3 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-66943-1024w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-66943-480w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-66943-480w.jpeg new file mode 100644 index 00000000..c40829b9 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-66943-480w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-66943-768w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-66943-768w.jpeg new file mode 100644 index 00000000..953ef6f3 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-66943-768w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-66943.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-66943.jpeg new file mode 100644 index 00000000..8dd20157 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-66943.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-787594-1024w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-787594-1024w.jpeg new file mode 100644 index 00000000..52113fef Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-787594-1024w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-787594-480w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-787594-480w.jpeg new file mode 100644 index 00000000..3b97fb45 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-787594-480w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-787594-768w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-787594-768w.jpeg new file mode 100644 index 00000000..b08cc133 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-787594-768w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-787594.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-787594.jpeg new file mode 100644 index 00000000..e2986131 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-787594.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-803105-1024w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-803105-1024w.jpeg new file mode 100644 index 00000000..99bb60cd Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-803105-1024w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-803105-480w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-803105-480w.jpeg new file mode 100644 index 00000000..815624dc Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-803105-480w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-803105-768w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-803105-768w.jpeg new file mode 100644 index 00000000..1118cde8 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-803105-768w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-803105.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-803105.jpeg new file mode 100644 index 00000000..8b7c44a4 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-803105.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-93750-1024w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-93750-1024w.jpeg new file mode 100644 index 00000000..bf1e8eaf Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-93750-1024w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-93750-480w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-93750-480w.jpeg new file mode 100644 index 00000000..08020dbe Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-93750-480w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-93750-768w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-93750-768w.jpeg new file mode 100644 index 00000000..8fe37d40 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-93750-768w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-93750.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-93750.jpeg new file mode 100644 index 00000000..ab537b02 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-93750.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-94420-1024w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-94420-1024w.jpeg new file mode 100644 index 00000000..c8a13148 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-94420-1024w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-94420-480w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-94420-480w.jpeg new file mode 100644 index 00000000..acc790e7 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-94420-480w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-94420-768w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-94420-768w.jpeg new file mode 100644 index 00000000..11fbaad9 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-94420-768w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-94420.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-94420.jpeg new file mode 100644 index 00000000..d3ebb012 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-94420.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-96947-1024w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-96947-1024w.jpeg new file mode 100644 index 00000000..3e4a701f Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-96947-1024w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-96947-480w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-96947-480w.jpeg new file mode 100644 index 00000000..0248070f Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-96947-480w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-96947-768w.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-96947-768w.jpeg new file mode 100644 index 00000000..c74f523e Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-96947-768w.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-96947.jpeg b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-96947.jpeg new file mode 100644 index 00000000..c6965748 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/pexels-photo-96947.jpeg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback-carousel1.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback-carousel1.jpg new file mode 100644 index 00000000..5ce2a4ed Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback-carousel1.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback-carousel2.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback-carousel2.jpg new file mode 100644 index 00000000..6417a30b Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback-carousel2.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback-carousel3.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback-carousel3.jpg new file mode 100644 index 00000000..a0939a7a Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback-carousel3.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback-carousel4.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback-carousel4.jpg new file mode 100644 index 00000000..5be118b7 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback-carousel4.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback-carousel5.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback-carousel5.jpg new file mode 100644 index 00000000..c61eb0ee Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback-carousel5.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback1.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback1.jpg new file mode 100644 index 00000000..2afb5530 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback1.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback2.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback2.jpg new file mode 100644 index 00000000..140e9718 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback2.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback3.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback3.jpg new file mode 100644 index 00000000..11115387 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback3.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback4.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback4.jpg new file mode 100644 index 00000000..9737793b Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback4.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback5.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback5.jpg new file mode 100644 index 00000000..88915773 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/fallback5.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/img1.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/img1.jpg new file mode 100644 index 00000000..68e10d14 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/img1.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/img2.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/img2.jpg new file mode 100644 index 00000000..3b69746a Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/img2.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/img3.png b/examples/angular-cli-material/src/assets/images/gallery/thumbs/img3.png new file mode 100644 index 00000000..3f0bf060 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/img3.png differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/img4.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/img4.jpg new file mode 100644 index 00000000..d08ebe7f Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/img4.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/img5.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/img5.jpg new file mode 100644 index 00000000..b932ee9f Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/img5.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg new file mode 100644 index 00000000..6881e08c Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg new file mode 100644 index 00000000..be93d546 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg new file mode 100644 index 00000000..eb99fe42 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg new file mode 100644 index 00000000..e33dc4be Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg new file mode 100644 index 00000000..feae47af Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg new file mode 100644 index 00000000..075cdd51 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg b/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg new file mode 100644 index 00000000..ab777557 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-106006-thumb.jpg b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-106006-thumb.jpg new file mode 100644 index 00000000..e80e1a53 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-106006-thumb.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-106006.jpg b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-106006.jpg new file mode 100644 index 00000000..6baa8325 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-106006.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-464336-thumb.jpg b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-464336-thumb.jpg new file mode 100644 index 00000000..7bd64447 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-464336-thumb.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-464336.jpg b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-464336.jpg new file mode 100644 index 00000000..c7253d57 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-464336.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-74506-thumb.jpg b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-74506-thumb.jpg new file mode 100644 index 00000000..24028aa0 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-74506-thumb.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-74506.jpg b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-74506.jpg new file mode 100644 index 00000000..c4973505 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-74506.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-thumb.jpg b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-thumb.jpg new file mode 100644 index 00000000..34615206 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo-thumb.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo.jpg b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo.jpg new file mode 100644 index 00000000..3ceffcbe Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/pexels-photo.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891-thumb.jpg b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891-thumb.jpg new file mode 100644 index 00000000..8cfda5fa Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891-thumb.jpg differ diff --git a/examples/angular-cli-material/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891.jpg b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891.jpg new file mode 100644 index 00000000..9457c1c6 Binary files /dev/null and b/examples/angular-cli-material/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891.jpg differ diff --git a/examples/angular-cli-material/src/assets/menu.svg b/examples/angular-cli-material/src/assets/menu.svg new file mode 100644 index 00000000..65fc9003 --- /dev/null +++ b/examples/angular-cli-material/src/assets/menu.svg @@ -0,0 +1,3 @@ + + + diff --git a/examples/angular-cli-material/src/favicon.png b/examples/angular-cli-material/src/favicon.png new file mode 100644 index 00000000..4e279875 Binary files /dev/null and b/examples/angular-cli-material/src/favicon.png differ diff --git a/examples/angular-cli-material/src/index.html b/examples/angular-cli-material/src/index.html new file mode 100644 index 00000000..2b54cea9 --- /dev/null +++ b/examples/angular-cli-material/src/index.html @@ -0,0 +1,15 @@ + + + + + @ks89/angular-modal-gallery demo + + + + + + + + + + diff --git a/examples/angular-cli-material/src/main.ts b/examples/angular-cli-material/src/main.ts new file mode 100644 index 00000000..1d335a67 --- /dev/null +++ b/examples/angular-cli-material/src/main.ts @@ -0,0 +1,8 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule, { + ngZoneEventCoalescing: true +}) + .catch(err => console.error(err)); diff --git a/examples/angular-cli-material/src/styles.scss b/examples/angular-cli-material/src/styles.scss new file mode 100644 index 00000000..47d84e5a --- /dev/null +++ b/examples/angular-cli-material/src/styles.scss @@ -0,0 +1,61 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// You can add global styles to this file, and also import other style files + +// ***************************************************************** +// *********** required by @ks89/angular-modal-gallery ************* +// ***************************************************************** +// ATTENTION: You have to install @angular/cdk to be able to use @ks89/angular-modal-gallery properly +@import "@angular/cdk/overlay-prebuilt.css"; + +.ks-modal-gallery-backdrop { + background: #000 !important;; + opacity: 0.85 !important;; +} + +.ks-modal-gallery-panel { + z-index: 90000 !important; +} +// ***************************************************************** +// ***************************************************************** +// ***************************************************************** + +body { + font-family: "Montserrat", sans-serif; + margin: 0; + padding: 0; +} + +// Not required by angular-modal-gallery. Used only in this demo +.red-text { + color: red; +} + +.title { + text-align: center; + color: red; +} + +.center-text { + text-align: center; +} diff --git a/examples/angular-cli-material/tsconfig.app.json b/examples/angular-cli-material/tsconfig.app.json new file mode 100644 index 00000000..3775b37e --- /dev/null +++ b/examples/angular-cli-material/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/examples/angular-cli-material/tsconfig.json b/examples/angular-cli-material/tsconfig.json new file mode 100644 index 00000000..3110e6e1 --- /dev/null +++ b/examples/angular-cli-material/tsconfig.json @@ -0,0 +1,32 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "compileOnSave": false, + "compilerOptions": { + "outDir": "./dist/out-tsc", + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "isolatedModules": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "moduleResolution": "bundler", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "useDefineForClassFields": false, // to inject sanitizer without errors + "lib": [ + "ES2022", + "dom" + ] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/examples/angular-cli-material/tsconfig.spec.json b/examples/angular-cli-material/tsconfig.spec.json new file mode 100644 index 00000000..5fb748d9 --- /dev/null +++ b/examples/angular-cli-material/tsconfig.spec.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/examples/stackblitz/README.md b/examples/stackblitz/README.md new file mode 100644 index 00000000..ce9196f9 --- /dev/null +++ b/examples/stackblitz/README.md @@ -0,0 +1,45 @@ +# angular-modal-gallery stackblitz.com demo + +angular-modal-gallery >= 8.x.x official stackblitz demos +- not available because stackblitz is not working properly with modal-gallery component + +angular-modal-gallery 7.x.x official stackblitz demo +- full size live demo [HERE](https://angular-modal-gallery-v7.stackblitz.io) +- editor view [HERE](https://stackblitz.com/edit/angular-modal-gallery-v7) + +angular-modal-gallery 6.x.x official stackblitz demo +- full size live demo [HERE](https://angular-modal-gallery-v6.stackblitz.io) +- editor view [HERE](https://stackblitz.com/edit/angular-modal-gallery-v6) + +angular-modal-gallery 5.x.x official stackblitz demo +- full size live demo [HERE](https://angular-modal-gallery-v5.stackblitz.io) +- editor view [HERE](https://stackblitz.com/edit/angular-modal-gallery-v5) + +angular-modal-gallery 4.x.x official stackblitz demo +- full size live demo [HERE](https://angular-modal-gallery-v4.stackblitz.io) +- editor view [HERE](https://stackblitz.com/edit/angular-modal-gallery-v4) + + +``` + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +``` diff --git a/examples/universal/.editorconfig b/examples/universal/.editorconfig new file mode 100644 index 00000000..59d9a3a3 --- /dev/null +++ b/examples/universal/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/examples/universal/.gitignore b/examples/universal/.gitignore new file mode 100644 index 00000000..0711527e --- /dev/null +++ b/examples/universal/.gitignore @@ -0,0 +1,42 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings + +# System files +.DS_Store +Thumbs.db diff --git a/examples/universal/.vscode/extensions.json b/examples/universal/.vscode/extensions.json new file mode 100644 index 00000000..77b37457 --- /dev/null +++ b/examples/universal/.vscode/extensions.json @@ -0,0 +1,4 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 + "recommendations": ["angular.ng-template"] +} diff --git a/examples/universal/.vscode/launch.json b/examples/universal/.vscode/launch.json new file mode 100644 index 00000000..925af837 --- /dev/null +++ b/examples/universal/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "ng serve", + "type": "chrome", + "request": "launch", + "preLaunchTask": "npm: start", + "url": "http://localhost:4200/" + }, + { + "name": "ng test", + "type": "chrome", + "request": "launch", + "preLaunchTask": "npm: test", + "url": "http://localhost:9876/debug.html" + } + ] +} diff --git a/examples/universal/.vscode/tasks.json b/examples/universal/.vscode/tasks.json new file mode 100644 index 00000000..a298b5bd --- /dev/null +++ b/examples/universal/.vscode/tasks.json @@ -0,0 +1,42 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "start", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "(.*?)" + }, + "endsPattern": { + "regexp": "bundle generation complete" + } + } + } + }, + { + "type": "npm", + "script": "test", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "(.*?)" + }, + "endsPattern": { + "regexp": "bundle generation complete" + } + } + } + } + ] +} diff --git a/examples/universal/angular.json b/examples/universal/angular.json new file mode 100644 index 00000000..ff884bb4 --- /dev/null +++ b/examples/universal/angular.json @@ -0,0 +1,118 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "universal": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss", + "standalone": false + }, + "@schematics/angular:directive": { + "standalone": false + }, + "@schematics/angular:pipe": { + "standalone": false + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:application", + "options": { + "outputPath": "dist/universal", + "index": "src/index.html", + "browser": "src/main.ts", + "polyfills": [ + "zone.js" + ], + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "src/favicon.png", + "src/assets", + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [], + "server": "src/main.server.ts", + "prerender": true, + "ssr": { + "entry": "src/server.ts" + } + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "2MB", + "maximumError": "5MB" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "6kb", + "maximumError": "10kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "universal:build:production" + }, + "development": { + "buildTarget": "universal:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n" + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "polyfills": [ + "zone.js", + "zone.js/testing" + ], + "tsConfig": "tsconfig.spec.json", + "inlineStyleLanguage": "scss", + "assets": [ + "src/favicon.png", + "src/assets", + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [] + } + } + } + } + } +} diff --git a/examples/universal/package-lock.json b/examples/universal/package-lock.json new file mode 100644 index 00000000..b32bb845 --- /dev/null +++ b/examples/universal/package-lock.json @@ -0,0 +1,13555 @@ +{ + "name": "angular-modal-gallery-universal-demo", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "angular-modal-gallery-universal-demo", + "version": "0.0.0", + "dependencies": { + "@angular/animations": "^19.0.5", + "@angular/cdk": "^19.0.4", + "@angular/common": "^19.0.5", + "@angular/compiler": "^19.0.5", + "@angular/core": "^19.0.5", + "@angular/forms": "^19.0.5", + "@angular/platform-browser": "^19.0.5", + "@angular/platform-browser-dynamic": "^19.0.5", + "@angular/platform-server": "^19.0.5", + "@angular/router": "^19.0.5", + "@angular/ssr": "^19.0.6", + "@fortawesome/fontawesome-svg-core": "^6.7.2", + "@fortawesome/free-solid-svg-icons": "^6.7.2", + "express": "^4.18.2", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^19.0.6", + "@angular/cli": "~19.0.6", + "@angular/compiler-cli": "^19.0.5", + "@types/express": "^4.17.17", + "@types/jasmine": "~5.1.0", + "@types/node": "^18.18.0", + "jasmine-core": "~5.1.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.6.3" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@angular-devkit/architect": { + "version": "0.1900.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1900.6.tgz", + "integrity": "sha512-w11bAXQnNWBawTJfQPjvaTRrzrqsOUm9tK9WNvaia/xjiRFpmO0CfmKtn3axNSEJM8jb/czaNQrgTwG+TGc/8g==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "19.0.6", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/architect/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/architect/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/architect/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/architect/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/build-angular": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-19.0.6.tgz", + "integrity": "sha512-dWTAsE6BSI8z0xglQdYBdqTBwg1Q+RWE3OrmlGs+520Dcoq/F0Z41Y1F3MiuHuQPdDAIQr88iB0APkIRW4clMg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1900.6", + "@angular-devkit/build-webpack": "0.1900.6", + "@angular-devkit/core": "19.0.6", + "@angular/build": "19.0.6", + "@babel/core": "7.26.0", + "@babel/generator": "7.26.2", + "@babel/helper-annotate-as-pure": "7.25.9", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-transform-async-generator-functions": "7.25.9", + "@babel/plugin-transform-async-to-generator": "7.25.9", + "@babel/plugin-transform-runtime": "7.25.9", + "@babel/preset-env": "7.26.0", + "@babel/runtime": "7.26.0", + "@discoveryjs/json-ext": "0.6.3", + "@ngtools/webpack": "19.0.6", + "@vitejs/plugin-basic-ssl": "1.1.0", + "ansi-colors": "4.1.3", + "autoprefixer": "10.4.20", + "babel-loader": "9.2.1", + "browserslist": "^4.21.5", + "copy-webpack-plugin": "12.0.2", + "css-loader": "7.1.2", + "esbuild-wasm": "0.24.0", + "fast-glob": "3.3.2", + "http-proxy-middleware": "3.0.3", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", + "karma-source-map-support": "1.4.0", + "less": "4.2.0", + "less-loader": "12.2.0", + "license-webpack-plugin": "4.0.2", + "loader-utils": "3.3.1", + "mini-css-extract-plugin": "2.9.2", + "open": "10.1.0", + "ora": "5.4.1", + "picomatch": "4.0.2", + "piscina": "4.7.0", + "postcss": "8.4.49", + "postcss-loader": "8.1.1", + "resolve-url-loader": "5.0.0", + "rxjs": "7.8.1", + "sass": "1.80.7", + "sass-loader": "16.0.3", + "semver": "7.6.3", + "source-map-loader": "5.0.0", + "source-map-support": "0.5.21", + "terser": "5.36.0", + "tree-kill": "1.2.2", + "tslib": "2.8.1", + "webpack": "5.96.1", + "webpack-dev-middleware": "7.4.2", + "webpack-dev-server": "5.1.0", + "webpack-merge": "6.0.1", + "webpack-subresource-integrity": "5.1.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "esbuild": "0.24.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^19.0.0", + "@angular/localize": "^19.0.0", + "@angular/platform-server": "^19.0.0", + "@angular/service-worker": "^19.0.0", + "@angular/ssr": "^19.0.6", + "@web/test-runner": "^0.19.0", + "browser-sync": "^3.0.2", + "jest": "^29.5.0", + "jest-environment-jsdom": "^29.5.0", + "karma": "^6.3.0", + "ng-packagr": "^19.0.0", + "protractor": "^7.0.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=5.5 <5.7" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "@web/test-runner": { + "optional": true + }, + "browser-sync": { + "optional": true + }, + "jest": { + "optional": true + }, + "jest-environment-jsdom": { + "optional": true + }, + "karma": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "protractor": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.1900.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1900.6.tgz", + "integrity": "sha512-WehtVrbBow4fc7hsaUKb+BZ6MDE5lO98/tgv7GR5PkRdGKnyLA0pW1AfPLJJQDgcaKjneramMhDFNc1eGSX0mQ==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1900.6", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "webpack": "^5.30.0", + "webpack-dev-server": "^5.0.2" + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.0.6.tgz", + "integrity": "sha512-R9hlHfAh1HKoIWgnYJlOEKhUezhTNl0fpUmHxG2252JSY5FLRxmYArTtJYYmbNdBbsBLNg3UHyM/GBPvJSA3NQ==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "19.0.6", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.12", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/animations": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-19.0.5.tgz", + "integrity": "sha512-HCOF2CrhUvjoZWusd4nh32VOxpUrg6bV+3Z8Q36Ix3aZdni8v0qoP2rl5wGbotaPtYg5RtyDH60Z2AOPKqlrZg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.0.5" + } + }, + "node_modules/@angular/build": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-19.0.6.tgz", + "integrity": "sha512-KEVNLgTZUF2dfpOYQn+yR2HONHUTxq/2rFVhiK9qAvrm/m+uKJNEXx7hGtbRyoqenZff4ScJq+7feITUldfX8g==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1900.6", + "@babel/core": "7.26.0", + "@babel/helper-annotate-as-pure": "7.25.9", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-syntax-import-attributes": "7.26.0", + "@inquirer/confirm": "5.0.2", + "@vitejs/plugin-basic-ssl": "1.1.0", + "beasties": "0.1.0", + "browserslist": "^4.23.0", + "esbuild": "0.24.0", + "fast-glob": "3.3.2", + "https-proxy-agent": "7.0.5", + "istanbul-lib-instrument": "6.0.3", + "listr2": "8.2.5", + "magic-string": "0.30.12", + "mrmime": "2.0.0", + "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "4.0.2", + "piscina": "4.7.0", + "rollup": "4.26.0", + "sass": "1.80.7", + "semver": "7.6.3", + "vite": "5.4.11", + "watchpack": "2.4.2" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "lmdb": "3.1.5" + }, + "peerDependencies": { + "@angular/compiler": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "@angular/localize": "^19.0.0", + "@angular/platform-server": "^19.0.0", + "@angular/service-worker": "^19.0.0", + "@angular/ssr": "^19.0.6", + "less": "^4.2.0", + "postcss": "^8.4.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=5.5 <5.7" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "less": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular/build/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular/build/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular/cdk": { + "version": "19.0.4", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-19.0.4.tgz", + "integrity": "sha512-P8V1n6AFFjBUJG3YRgw8DiiNDWPZVrwQ42wbwgZxd4s2TQAuNFg3YY8h/DSMVxt2sXpavrshZsoLtP9yLKZjHA==", + "dependencies": { + "tslib": "^2.3.0" + }, + "optionalDependencies": { + "parse5": "^7.1.2" + }, + "peerDependencies": { + "@angular/common": "^19.0.0 || ^20.0.0", + "@angular/core": "^19.0.0 || ^20.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/cli": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-19.0.6.tgz", + "integrity": "sha512-ZEHhgRRVIdn10dbsAjB8TE9Co32hfuL9/im5Jcfa1yrn6KJefmigz6KN8Xu7FXMH5FkdqfQ11QpLBxJSPb9aww==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1900.6", + "@angular-devkit/core": "19.0.6", + "@angular-devkit/schematics": "19.0.6", + "@inquirer/prompts": "7.1.0", + "@listr2/prompt-adapter-inquirer": "2.0.18", + "@schematics/angular": "19.0.6", + "@yarnpkg/lockfile": "1.1.0", + "ini": "5.0.0", + "jsonc-parser": "3.3.1", + "listr2": "8.2.5", + "npm-package-arg": "12.0.0", + "npm-pick-manifest": "10.0.0", + "pacote": "20.0.0", + "resolve": "1.22.8", + "semver": "7.6.3", + "symbol-observable": "4.0.0", + "yargs": "17.7.2" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/cli/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular/cli/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular/cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/cli/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/cli/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular/common": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-19.0.5.tgz", + "integrity": "sha512-fFK+euCj1AjBHBCpj9VnduMSeqoMRhZZHbhPYiND7tucRRJ8vwGU0sYK2KI/Ko+fsrNIXL/0O4F36jVPl09Smg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.0.5", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/compiler": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-19.0.5.tgz", + "integrity": "sha512-S8ku5Ljp0kqX3shfmE9DVo09629jeYJSlBRGbj2Glb92dd+VQZPOz7KxqKRTwmAl7lQIV/+4Lr6G/GVTsoC4vg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.0.5" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + } + } + }, + "node_modules/@angular/compiler-cli": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.0.5.tgz", + "integrity": "sha512-KSzuWCTZlvJsoAenxM9cjTOzNM8mrFxDBInj0KVPz7QU83amGS4rcv1pWO/QGYQcErfskcN84TAdMegaRWWCmA==", + "dev": true, + "dependencies": { + "@babel/core": "7.26.0", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^4.0.0", + "convert-source-map": "^1.5.1", + "reflect-metadata": "^0.2.0", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^17.2.1" + }, + "bin": { + "ng-xi18n": "bundles/src/bin/ng_xi18n.js", + "ngc": "bundles/src/bin/ngc.js", + "ngcc": "bundles/ngcc/index.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/compiler": "19.0.5", + "typescript": ">=5.5 <5.7" + } + }, + "node_modules/@angular/compiler-cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/compiler-cli/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/core": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-19.0.5.tgz", + "integrity": "sha512-Ywc6sPO6G/Y1stfk3y/MallV/h0yzQ0vdOHRWueLrk5kD1DTdbolV4X03Cs3PuVvravgcSVE3nnuuHFuH32emQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.15.0" + } + }, + "node_modules/@angular/forms": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-19.0.5.tgz", + "integrity": "sha512-OhNFkfOoguqCDq07vNBV28FFrmTM8S11Z3Cd6PQZJJF9TgAtpV5KtF7A3eXBCN92W4pmqluomPjfK7YyImzIYQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.0.5", + "@angular/core": "19.0.5", + "@angular/platform-browser": "19.0.5", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.0.5.tgz", + "integrity": "sha512-41+Jo5DEil4Ifvv+UE/p1l9YJtYN+xfhx+/C9cahVgvV5D2q+givyK73d0Mnb6XOfe1q+hoV5lZ+XhQYp21//g==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/animations": "19.0.5", + "@angular/common": "19.0.5", + "@angular/core": "19.0.5" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/platform-browser-dynamic": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-19.0.5.tgz", + "integrity": "sha512-KKFdue/uJVxkWdrntRAXkz+ycp4nD3SuGOH5pPf2svCBxieuHuFlWDi+DYVuFSEpC/ICCmlhrtzIAm44A4qzzQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.0.5", + "@angular/compiler": "19.0.5", + "@angular/core": "19.0.5", + "@angular/platform-browser": "19.0.5" + } + }, + "node_modules/@angular/platform-server": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-19.0.5.tgz", + "integrity": "sha512-fcJ4L9sLYW/5LBL/mCxjWMyLhOX3EJVY9ldzVNbRlzD4DRhPfUgVJwgYYlCVvWZclnCH4CdUo+VrshWMZF5NJQ==", + "dependencies": { + "tslib": "^2.3.0", + "xhr2": "^0.2.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/animations": "19.0.5", + "@angular/common": "19.0.5", + "@angular/compiler": "19.0.5", + "@angular/core": "19.0.5", + "@angular/platform-browser": "19.0.5" + } + }, + "node_modules/@angular/router": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-19.0.5.tgz", + "integrity": "sha512-6tNubVVj/rRyTg+OXjQxACfufvCLHAwDQtv9wqt6q/3OYSnysHTik3ho3FaFPwu7fXJ+6p9Rjzkh2VY9QMk4bw==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.0.5", + "@angular/core": "19.0.5", + "@angular/platform-browser": "19.0.5", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/ssr": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular/ssr/-/ssr-19.0.6.tgz", + "integrity": "sha512-T9UfqqaWw9OKzJI+2RELMqPDD3uFtJt4CLBWDQIeG1GR51RFM4K7oeP+oQ14ohe9w/Ysyh1s1KyXAY+Vaaggbw==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "^19.0.0", + "@angular/core": "^19.0.0", + "@angular/platform-server": "^19.0.0", + "@angular/router": "^19.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", + "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.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/convert-source-map": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "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==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.26.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz", + "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", + "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", + "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.38.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.26.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", + "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.3", + "@babel/parser": "^7.26.3", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.3", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", + "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.26.3", + "@babel/types": "^7.26.3", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", + "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", + "dev": true, + "engines": { + "node": ">=14.17.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", + "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz", + "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz", + "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz", + "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz", + "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz", + "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz", + "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz", + "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz", + "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz", + "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz", + "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz", + "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz", + "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz", + "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz", + "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz", + "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz", + "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz", + "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz", + "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz", + "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz", + "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz", + "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz", + "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz", + "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.2.tgz", + "integrity": "sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.2.tgz", + "integrity": "sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.2.tgz", + "integrity": "sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.0.4.tgz", + "integrity": "sha512-fYAKCAcGNMdfjL6hZTRUwkIByQ8EIZCXKrIQZH7XjADnN/xvRUhj8UdBbpC4zoUzvChhkSC/zRKaP/tDs3dZpg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.0.2.tgz", + "integrity": "sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/core": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.2.tgz", + "integrity": "sha512-bHd96F3ezHg1mf/J0Rb4CV8ndCN0v28kUlrHqP7+ECm1C/A+paB7Xh2lbMk6x+kweQC+rZOxM/YeKikzxco8bQ==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core/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==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.1.tgz", + "integrity": "sha512-xn9aDaiP6nFa432i68JCaL302FyL6y/6EG97nAtfIPnWZ+mWPgCMLGc4XZ2QQMsZtu9q3Jd5AzBPjXh10aX9kA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.4.tgz", + "integrity": "sha512-GYocr+BPyxKPxQ4UZyNMqZFSGKScSUc0Vk17II3J+0bDcgGsQm0KYQNooN1Q5iBfXsy3x/VWmHGh20QnzsaHwg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.9.tgz", + "integrity": "sha512-BXvGj0ehzrngHTPTDqUoDT3NXL8U0RxUk2zJm2A66RhCEIWdtU1v6GuUqNAgArW4PQ9CinqIWyHdQgdwOj06zQ==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.1.tgz", + "integrity": "sha512-nAXAHQndZcXB+7CyjIW3XuQZZHbQQ0q8LX6miY6bqAWwDzNa9JUioDBYrFmOUNIsuF08o1WT/m2gbBXvBhYVxg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.4.tgz", + "integrity": "sha512-DX7a6IXRPU0j8kr2ovf+QaaDiIf+zEKaZVzCWdLOTk7XigqSXvoh4cul7x68xp54WTQrgSnW7P1WBJDbyY3GhA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.4.tgz", + "integrity": "sha512-wiliQOWdjM8FnBmdIHtQV2Ca3S1+tMBUerhyjkRCv1g+4jSvEweGu9GCcvVEgKDhTBT15nrxvk5/bVrGUqSs1w==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.1.0.tgz", + "integrity": "sha512-5U/XiVRH2pp1X6gpNAjWOglMf38/Ys522ncEHIKT1voRUvSj/DQnR22OVxHnwu5S+rCFaUiPQ57JOtMFQayqYA==", + "dev": true, + "dependencies": { + "@inquirer/checkbox": "^4.0.2", + "@inquirer/confirm": "^5.0.2", + "@inquirer/editor": "^4.1.0", + "@inquirer/expand": "^4.0.2", + "@inquirer/input": "^4.0.2", + "@inquirer/number": "^3.0.2", + "@inquirer/password": "^4.0.2", + "@inquirer/rawlist": "^4.0.2", + "@inquirer/search": "^3.0.2", + "@inquirer/select": "^4.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.0.4.tgz", + "integrity": "sha512-IsVN2EZdNHsmFdKWx9HaXb8T/s3FlR/U1QPt9dwbSyPtjFbMTlW9CRFvnn0bm/QIsrMRD2oMZqrQpSWPQVbXXg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/search": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.4.tgz", + "integrity": "sha512-tSkJk2SDmC2MEdTIjknXWmCnmPr5owTs9/xjfa14ol1Oh95n6xW7SYn5fiPk4/vrJPys0ggSWiISdPze4LTa7A==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/select": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.0.4.tgz", + "integrity": "sha512-ZzYLuLoUzTIW9EJm++jBpRiTshGqS3Q1o5qOEQqgzaBlmdsjQr6pA4TUNkwu6OBYgM2mIRbCz6mUhFDfl/GF+w==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.2.tgz", + "integrity": "sha512-ZhQ4TvhwHZF+lGhQ2O/rsjo80XoZR5/5qhOY3t6FJuX5XBg5Be8YzYTvaUGJnc12AUGI2nr4QSUE4PhKSigx7g==", + "dev": true, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/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==", + "dev": true + }, + "node_modules/@isaacs/cliui/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==", + "dev": true, + "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/@isaacs/cliui/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/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==", + "dev": true, + "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/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "dev": true, + "license": "MIT", + "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.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.1.tgz", + "integrity": "sha512-osjeBqMJ2lb/j/M8NCPjs1ylqWIcTRTycIhVB5pt6LgzgeRSb0YRZ7j9RfA8wIUrsr/medIuhVyonXRZWLyfdw==", + "dev": true, + "dependencies": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.5.0.tgz", + "integrity": "sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true + }, + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.18.tgz", + "integrity": "sha512-0hz44rAcrphyXcA8IS7EJ2SCoaBZD2u5goE8S/e+q/DL+dOGpqpcLidVOFeLG3VgML62SXmfRLAhWt0zL1oW4Q==", + "dev": true, + "dependencies": { + "@inquirer/type": "^1.5.5" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 8" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/@inquirer/type": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", + "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", + "dev": true, + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.1.5.tgz", + "integrity": "sha512-ue5PSOzHMCIYrfvPP/MRS6hsKKLzqqhcdAvJCO8uFlDdj598EhgnacuOTuqA6uBK5rgiZXfDWyb7DVZSiBKxBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.1.5.tgz", + "integrity": "sha512-CGhsb0R5vE6mMNCoSfxHFD8QTvBHM51gs4DBeigTYHWnYv2V5YpJkC4rMo5qAAFifuUcc0+a8a3SIU0c9NrfNw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.1.5.tgz", + "integrity": "sha512-3WeW328DN+xB5PZdhSWmqE+t3+44xWXEbqQ+caWJEZfOFdLp9yklBZEbVqVdqzznkoaXJYxTCp996KD6HmANeg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.1.5.tgz", + "integrity": "sha512-LAjaoOcBHGj6fiYB8ureiqPoph4eygbXu4vcOF+hsxiY74n8ilA7rJMmGUT0K0JOB5lmRQHSmor3mytRjS4qeQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.1.5.tgz", + "integrity": "sha512-k/IklElP70qdCXOQixclSl2GPLFiopynGoKX1FqDd1/H0E3Fo1oPwjY2rEVu+0nS3AOw1sryStdXk8CW3cVIsw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.1.5.tgz", + "integrity": "sha512-KYar6W8nraZfSJspcK7Kp7hdj238X/FNauYbZyrqPBrtsXI1hvI4/KcRcRGP50aQoV7fkKDyJERlrQGMGTZUsA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@napi-rs/nice": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.0.1.tgz", + "integrity": "sha512-zM0mVWSXE0a0h9aKACLwKmD6nHcRiKrPpCfvaKqG1CqDEyjEawId0ocXxVzPMCAm6kkWr2P025msfxXEnt8UGQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/nice-android-arm-eabi": "1.0.1", + "@napi-rs/nice-android-arm64": "1.0.1", + "@napi-rs/nice-darwin-arm64": "1.0.1", + "@napi-rs/nice-darwin-x64": "1.0.1", + "@napi-rs/nice-freebsd-x64": "1.0.1", + "@napi-rs/nice-linux-arm-gnueabihf": "1.0.1", + "@napi-rs/nice-linux-arm64-gnu": "1.0.1", + "@napi-rs/nice-linux-arm64-musl": "1.0.1", + "@napi-rs/nice-linux-ppc64-gnu": "1.0.1", + "@napi-rs/nice-linux-riscv64-gnu": "1.0.1", + "@napi-rs/nice-linux-s390x-gnu": "1.0.1", + "@napi-rs/nice-linux-x64-gnu": "1.0.1", + "@napi-rs/nice-linux-x64-musl": "1.0.1", + "@napi-rs/nice-win32-arm64-msvc": "1.0.1", + "@napi-rs/nice-win32-ia32-msvc": "1.0.1", + "@napi-rs/nice-win32-x64-msvc": "1.0.1" + } + }, + "node_modules/@napi-rs/nice-android-arm-eabi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.1.tgz", + "integrity": "sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-android-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.0.1.tgz", + "integrity": "sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.0.1.tgz", + "integrity": "sha512-91k3HEqUl2fsrz/sKkuEkscj6EAj3/eZNCLqzD2AA0TtVbkQi8nqxZCZDMkfklULmxLkMxuUdKe7RvG/T6s2AA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.1.tgz", + "integrity": "sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-freebsd-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.0.1.tgz", + "integrity": "sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.0.1.tgz", + "integrity": "sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.0.1.tgz", + "integrity": "sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-musl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.0.1.tgz", + "integrity": "sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-ppc64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.0.1.tgz", + "integrity": "sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-riscv64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.0.1.tgz", + "integrity": "sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-s390x-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.0.1.tgz", + "integrity": "sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.0.1.tgz", + "integrity": "sha512-XQAJs7DRN2GpLN6Fb+ZdGFeYZDdGl2Fn3TmFlqEL5JorgWKrQGRUrpGKbgZ25UeZPILuTKJ+OowG2avN8mThBA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-musl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.0.1.tgz", + "integrity": "sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-arm64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.0.1.tgz", + "integrity": "sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-ia32-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.0.1.tgz", + "integrity": "sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-x64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.0.1.tgz", + "integrity": "sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ngtools/webpack": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-19.0.6.tgz", + "integrity": "sha512-eWrIb0tS1CK6+JvFS4GgTD4fN9TtmApKrlaj3pPQXKXKKd42361ec85fuQQXdb4G8eEEq0vyd/bn4NJllh/3vw==", + "dev": true, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^19.0.0", + "typescript": ">=5.5 <5.7", + "webpack": "^5.54.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz", + "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/@npmcli/fs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz", + "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-6.0.1.tgz", + "integrity": "sha512-BBWMMxeQzalmKadyimwb2/VVQyJB01PH0HhVSNLHNBDZN/M/h/02P6f8fxedIiFhpMj11SO9Ep5tKTBE7zL2nw==", + "dev": true, + "dependencies": { + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-3.0.0.tgz", + "integrity": "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q==", + "dev": true, + "dependencies": { + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-6.1.0.tgz", + "integrity": "sha512-t6G+6ZInT4X+tqj2i+wlLIeCKnKOTuz9/VFYDtj+TGTur5q7sp/OYrQA19LdBbWfXDOi0Y4jtedV6xtB8zQ9ug==", + "dev": true, + "dependencies": { + "@npmcli/git": "^6.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "normalize-package-data": "^7.0.0", + "proc-log": "^5.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/package-json/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-8.0.2.tgz", + "integrity": "sha512-/bNJhjc+o6qL+Dwz/bqfTQClkEO5nTQ1ZEcdCkAQjhkZMHIh22LPG7fNh1enJP1NKWDqYiiABnjFCY7E0zHYtQ==", + "dev": true, + "dependencies": { + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-3.0.0.tgz", + "integrity": "sha512-/1uFzjVcfzqrgCeGW7+SZ4hv0qLWmKXVzFahZGJ6QuJBj6Myt9s17+JL86i76NV9YSnJRcGXJYQbAU0rn1YTCQ==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-9.0.2.tgz", + "integrity": "sha512-cJXiUlycdizQwvqE1iaAb4VRUM3RX09/8q46zjvy+ct9GhfZRWd7jXYVc1tn/CfRlGPVkX/u4sstRlepsm7hfw==", + "dev": true, + "dependencies": { + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "node-gyp": "^11.0.0", + "proc-log": "^5.0.0", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.0.tgz", + "integrity": "sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.0", + "@parcel/watcher-darwin-arm64": "2.5.0", + "@parcel/watcher-darwin-x64": "2.5.0", + "@parcel/watcher-freebsd-x64": "2.5.0", + "@parcel/watcher-linux-arm-glibc": "2.5.0", + "@parcel/watcher-linux-arm-musl": "2.5.0", + "@parcel/watcher-linux-arm64-glibc": "2.5.0", + "@parcel/watcher-linux-arm64-musl": "2.5.0", + "@parcel/watcher-linux-x64-glibc": "2.5.0", + "@parcel/watcher-linux-x64-musl": "2.5.0", + "@parcel/watcher-win32-arm64": "2.5.0", + "@parcel/watcher-win32-ia32": "2.5.0", + "@parcel/watcher-win32-x64": "2.5.0" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.0.tgz", + "integrity": "sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.0.tgz", + "integrity": "sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.0.tgz", + "integrity": "sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.0.tgz", + "integrity": "sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.0.tgz", + "integrity": "sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.0.tgz", + "integrity": "sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.0.tgz", + "integrity": "sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.0.tgz", + "integrity": "sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.0.tgz", + "integrity": "sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.0.tgz", + "integrity": "sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.0.tgz", + "integrity": "sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.0.tgz", + "integrity": "sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.0.tgz", + "integrity": "sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@parcel/watcher/node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "optional": true + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.26.0.tgz", + "integrity": "sha512-gJNwtPDGEaOEgejbaseY6xMFu+CPltsc8/T+diUTTbOQLqD+bnrJq9ulH6WD69TqwqWmrfRAtUv30cCFZlbGTQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.26.0.tgz", + "integrity": "sha512-YJa5Gy8mEZgz5JquFruhJODMq3lTHWLm1fOy+HIANquLzfIOzE9RA5ie3JjCdVb9r46qfAQY/l947V0zfGJ0OQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.26.0.tgz", + "integrity": "sha512-ErTASs8YKbqTBoPLp/kA1B1Um5YSom8QAc4rKhg7b9tyyVqDBlQxy7Bf2wW7yIlPGPg2UODDQcbkTlruPzDosw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.26.0.tgz", + "integrity": "sha512-wbgkYDHcdWW+NqP2mnf2NOuEbOLzDblalrOWcPyY6+BRbVhliavon15UploG7PpBRQ2bZJnbmh8o3yLoBvDIHA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.26.0.tgz", + "integrity": "sha512-Y9vpjfp9CDkAG4q/uwuhZk96LP11fBz/bYdyg9oaHYhtGZp7NrbkQrj/66DYMMP2Yo/QPAsVHkV891KyO52fhg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.26.0.tgz", + "integrity": "sha512-A/jvfCZ55EYPsqeaAt/yDAG4q5tt1ZboWMHEvKAH9Zl92DWvMIbnZe/f/eOXze65aJaaKbL+YeM0Hz4kLQvdwg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.26.0.tgz", + "integrity": "sha512-paHF1bMXKDuizaMODm2bBTjRiHxESWiIyIdMugKeLnjuS1TCS54MF5+Y5Dx8Ui/1RBPVRE09i5OUlaLnv8OGnA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.26.0.tgz", + "integrity": "sha512-cwxiHZU1GAs+TMxvgPfUDtVZjdBdTsQwVnNlzRXC5QzIJ6nhfB4I1ahKoe9yPmoaA/Vhf7m9dB1chGPpDRdGXg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.26.0.tgz", + "integrity": "sha512-4daeEUQutGRCW/9zEo8JtdAgtJ1q2g5oHaoQaZbMSKaIWKDQwQ3Yx0/3jJNmpzrsScIPtx/V+1AfibLisb3AMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.26.0.tgz", + "integrity": "sha512-eGkX7zzkNxvvS05ROzJ/cO/AKqNvR/7t1jA3VZDi2vRniLKwAWxUr85fH3NsvtxU5vnUUKFHKh8flIBdlo2b3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.26.0.tgz", + "integrity": "sha512-Odp/lgHbW/mAqw/pU21goo5ruWsytP7/HCC/liOt0zcGG0llYWKrd10k9Fj0pdj3prQ63N5yQLCLiE7HTX+MYw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.26.0.tgz", + "integrity": "sha512-MBR2ZhCTzUgVD0OJdTzNeF4+zsVogIR1U/FsyuFerwcqjZGvg2nYe24SAHp8O5sN8ZkRVbHwlYeHqcSQ8tcYew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.26.0.tgz", + "integrity": "sha512-YYcg8MkbN17fMbRMZuxwmxWqsmQufh3ZJFxFGoHjrE7bv0X+T6l3glcdzd7IKLiwhT+PZOJCblpnNlz1/C3kGQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.26.0.tgz", + "integrity": "sha512-ZuwpfjCwjPkAOxpjAEjabg6LRSfL7cAJb6gSQGZYjGhadlzKKywDkCUnJ+KEfrNY1jH5EEoSIKLCb572jSiglA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.26.0.tgz", + "integrity": "sha512-+HJD2lFS86qkeF8kNu0kALtifMpPCZU80HvwztIKnYwym3KnA1os6nsX4BGSTLtS2QVAGG1P3guRgsYyMA0Yhg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.26.0.tgz", + "integrity": "sha512-WUQzVFWPSw2uJzX4j6YEbMAiLbs0BUysgysh8s817doAYhR5ybqTI1wtKARQKo6cGop3pHnrUJPFCsXdoFaimQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.26.0.tgz", + "integrity": "sha512-D4CxkazFKBfN1akAIY6ieyOqzoOoBV1OICxgUblWxff/pSjCA2khXlASUx7mK6W1oP4McqhgcCsu6QaLj3WMWg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.26.0.tgz", + "integrity": "sha512-2x8MO1rm4PGEP0xWbubJW5RtbNLk3puzAMaLQd3B3JHVw4KcHlmXcO+Wewx9zCoo7EUFiMlu/aZbCJ7VjMzAag==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@schematics/angular": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-19.0.6.tgz", + "integrity": "sha512-HicclmbW/+mlljU7a4PzbyIWG+7tognoL5LsgMFJQUDzJXHNjRt1riL0vk57o8Pcprnz9FheeWZXO1KRhXkQuw==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "19.0.6", + "@angular-devkit/schematics": "19.0.6", + "jsonc-parser": "3.3.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@schematics/angular/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@schematics/angular/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@schematics/angular/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@sigstore/bundle": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-3.0.0.tgz", + "integrity": "sha512-XDUYX56iMPAn/cdgh/DTJxz5RWmqKV4pwvUAEKEWJl+HzKdCd/24wUa9JYNMlDSCb7SUHAdtksxYX779Nne/Zg==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-2.0.0.tgz", + "integrity": "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.2.tgz", + "integrity": "sha512-c6B0ehIWxMI8wiS/bj6rHMPqeFvngFV7cDU/MY+B16P9Z3Mp9k8L93eYZ7BYzSickzuqAQqAq0V956b3Ju6mLw==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-3.0.0.tgz", + "integrity": "sha512-UjhDMQOkyDoktpXoc5YPJpJK6IooF2gayAr5LvXI4EL7O0vd58okgfRcxuaH+YTdhvb5aa1Q9f+WJ0c2sVuYIw==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^14.0.1", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-3.0.0.tgz", + "integrity": "sha512-9Xxy/8U5OFJu7s+OsHzI96IX/OzjF/zj0BSSaWhgJgTqtlBhQIV2xdrQI5qxLD7+CWWDepadnXAxzaZ3u9cvRw==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2", + "tuf-js": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-2.0.0.tgz", + "integrity": "sha512-Ggtq2GsJuxFNUvQzLoXqRwS4ceRfLAJnrIHUDrzAD0GgnOhwujJkKkxM/s5Bako07c3WtAs/sZo5PJq7VHjeDg==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-3.0.1.tgz", + "integrity": "sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==", + "dev": true, + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@tufjs/models/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/cors": { + "version": "2.8.17", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.21", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/jasmine": { + "version": "5.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "18.19.33", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.9.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.1.0.tgz", + "integrity": "sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A==", + "dev": true, + "engines": { + "node": ">=14.6.0" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-loader": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", + "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", + "dev": true, + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.3", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.3" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/base64id": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/beasties": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.1.0.tgz", + "integrity": "sha512-+Ssscd2gVG24qRNC+E2g88D+xsQW4xwakWtKAiGEQ3Pw54/FGdyo9RrfxhGhEv6ilFVbB7r3Lgx+QnAxnSpECw==", + "dev": true, + "dependencies": { + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "htmlparser2": "^9.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-media-query-parser": "^0.2.3" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "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==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz", + "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==", + "dev": true, + "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.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz", + "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^4.0.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001690", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", + "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", + "dev": true, + "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/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/chokidar": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "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" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "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/cli-truncate/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "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==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT" + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", + "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.0.2", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/connect": { + "version": "3.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/finalhandler": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/connect/node_modules/on-finished": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/connect/node_modules/statuses": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.6.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "license": "MIT" + }, + "node_modules/copy-anything": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", + "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", + "dev": true, + "dependencies": { + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.1", + "globby": "^14.0.0", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/core-js-compat": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", + "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==", + "dev": true, + "dependencies": { + "browserslist": "^4.24.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cors": { + "version": "2.8.5", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cosmiconfig/node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/cosmiconfig/node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", + "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", + "dev": true, + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "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==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/custom-event": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/date-format": { + "version": "4.0.14", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/di": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.75", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.75.tgz", + "integrity": "sha512-Lf3++DumRE/QmweGjU+ZcKqQ+3bKkU/qjaKYhIJKEOhgIO9Xs6IiAQFkfFoj+RhgDk4LUeNsLo6plExHqSyu6Q==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/engine.io": { + "version": "6.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/cookie": { + "version": "0.4.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", + "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ent": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/entities": { + "version": "4.5.0", + "devOptional": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "node_modules/errno": { + "version": "0.1.8", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.3", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz", + "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.0", + "@esbuild/android-arm": "0.24.0", + "@esbuild/android-arm64": "0.24.0", + "@esbuild/android-x64": "0.24.0", + "@esbuild/darwin-arm64": "0.24.0", + "@esbuild/darwin-x64": "0.24.0", + "@esbuild/freebsd-arm64": "0.24.0", + "@esbuild/freebsd-x64": "0.24.0", + "@esbuild/linux-arm": "0.24.0", + "@esbuild/linux-arm64": "0.24.0", + "@esbuild/linux-ia32": "0.24.0", + "@esbuild/linux-loong64": "0.24.0", + "@esbuild/linux-mips64el": "0.24.0", + "@esbuild/linux-ppc64": "0.24.0", + "@esbuild/linux-riscv64": "0.24.0", + "@esbuild/linux-s390x": "0.24.0", + "@esbuild/linux-x64": "0.24.0", + "@esbuild/netbsd-x64": "0.24.0", + "@esbuild/openbsd-arm64": "0.24.0", + "@esbuild/openbsd-x64": "0.24.0", + "@esbuild/sunos-x64": "0.24.0", + "@esbuild/win32-arm64": "0.24.0", + "@esbuild/win32-ia32": "0.24.0", + "@esbuild/win32-x64": "0.24.0" + } + }, + "node_modules/esbuild-wasm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.24.0.tgz", + "integrity": "sha512-xhNn5tL1AhkPg4ft59yXT6FkwKXiPSYyz1IeinJHUJpjvOHOIPvdmFQc0pGdjxlKSbzZc2mNmtVOWAR1EF/JAg==", + "dev": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true + }, + "node_modules/express": { + "version": "4.19.2", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/extend": { + "version": "3.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dev": true, + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/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==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "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", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "dev": true, + "license": "BSD-2-Clause" + }, + "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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "dev": true, + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.0.2.tgz", + "integrity": "sha512-sYKnA7eGln5ov8T8gnYlkSOxFJvywzEx9BueN6xo/GKO8PGiI6uK6xx+DIGe45T3bdVjLAQDQW1aicT8z8JwQg==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "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==", + "dev": true + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-middleware": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.3.tgz", + "integrity": "sha512-usY0HG5nyDUwtqpiZdETNbmKtw3QQ1jwYFZ9wi5iHzX2BcILwQKtYDJPo7XHTsu5Z0B2Hj3W9NNnbd+AjFWjqg==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.15", + "debug": "^4.3.6", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.3", + "is-plain-object": "^5.0.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-middleware/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-7.0.0.tgz", + "integrity": "sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ==", + "dev": true, + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ignore-walk/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immutable": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "license": "ISC" + }, + "node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "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-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "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": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jasmine-core": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.0", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "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==", + "dev": true + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", + "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/karma": { + "version": "6.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.7.2", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-chrome-launcher": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "which": "^1.2.1" + } + }, + "node_modules/karma-coverage": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.0.5", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/karma-jasmine": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "jasmine-core": "^4.1.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "karma": "^6.0.0" + } + }, + "node_modules/karma-jasmine-html-reporter": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "peerDependencies": { + "jasmine-core": "^4.0.0 || ^5.0.0", + "karma": "^6.0.0", + "karma-jasmine": "^5.0.0" + } + }, + "node_modules/karma-jasmine/node_modules/jasmine-core": { + "version": "4.6.1", + "dev": true, + "license": "MIT" + }, + "node_modules/karma-source-map-support": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map-support": "^0.5.5" + } + }, + "node_modules/karma/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/karma/node_modules/cliui": { + "version": "7.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/karma/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/karma/node_modules/tmp": { + "version": "0.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/karma/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/karma/node_modules/yargs": { + "version": "16.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/karma/node_modules/yargs-parser": { + "version": "20.2.9", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/launch-editor": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/less": { + "version": "4.2.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less-loader": { + "version": "12.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "less": "^3.5.0 || ^4.0.0", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/less/node_modules/make-dir": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/mime": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/less/node_modules/semver": { + "version": "5.7.2", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/less/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/license-webpack-plugin": { + "version": "4.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "webpack-sources": "^3.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-sources": { + "optional": true + } + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", + "integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "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/listr2/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/lmdb": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.1.5.tgz", + "integrity": "sha512-46Mch5Drq+A93Ss3gtbg+Xuvf5BOgIuvhKDWoGa3HcPHI6BL2NCOkRdSx1D4VfzwrxhnsjbyIVsLRlQHu6URvw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "msgpackr": "^1.11.2", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.2.2", + "ordered-binary": "^1.5.3", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "3.1.5", + "@lmdb/lmdb-darwin-x64": "3.1.5", + "@lmdb/lmdb-linux-arm": "3.1.5", + "@lmdb/lmdb-linux-arm64": "3.1.5", + "@lmdb/lmdb-linux-x64": "3.1.5", + "@lmdb/lmdb-win32-x64": "3.1.5" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/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==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "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/log-update/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/log4js": { + "version": "6.9.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-fetch-happen": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", + "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==", + "dev": true, + "dependencies": { + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/make-fetch-happen/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.15.1.tgz", + "integrity": "sha512-ufCzgFwiVnR6R9cCYuvwznJdhdYXEvFl0hpnM4cCtVaVkHuqBR+6fo2sqt1SSMdp+uiHw9GyPZr3OMM5tqjSmQ==", + "dev": true, + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.3.0", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", + "dev": true, + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.0.tgz", + "integrity": "sha512-2v6aXUXwLP1Epd/gc32HAMIWoczx+fZwEPRHm/VwtrJzRGwR1qGZXEYV3Zp8ZjjbwaZhMrM6uHV4KVkk+XCc2w==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/minizlib/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/minizlib/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minizlib/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minizlib/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/msgpackr": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz", + "integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==", + "dev": true, + "optional": true, + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/needle": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "optional": true + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.0.0.tgz", + "integrity": "sha512-zQS+9MTTeCMgY0F3cWPyJyRFAkVltQ1uXm+xXu/ES6KFgC6Czo1Seb9vQW2wNxSX2OrDTiqL0ojtkFxBQ0ypIw==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^14.0.3", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "tar": "^7.4.3", + "which": "^5.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-gyp/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/node-gyp/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/node-gyp/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true + }, + "node_modules/nopt": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.0.0.tgz", + "integrity": "sha512-1L/fTJ4UmV/lUxT2Uf006pfZKTvAgCF+chz+0OgBHO8u2Z67pE7AaAUUj7CJy0lXqHmymUvGFt6NE9R3HER0yw==", + "dev": true, + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/normalize-package-data": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-7.0.0.tgz", + "integrity": "sha512-k6U0gKRIuNCTkwHGZqblCfLfBRh+w1vI6tBo+IeJwq2M8FUiOqhX7GH+GArQGScA7azd1WfyRCvxoXDO3hQDIA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^8.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-bundled": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-4.0.0.tgz", + "integrity": "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA==", + "dev": true, + "dependencies": { + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-install-checks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-7.1.1.tgz", + "integrity": "sha512-u6DCwbow5ynAX5BdiHQ9qvexme4U3qHW3MWe5NqH+NeBm0LbiH6zvGjNNew1fY+AZZUtVHbOPF3j7mJxbUzpXg==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", + "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-package-arg": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.0.tgz", + "integrity": "sha512-ZTE0hbwSdTNL+Stx2zxSqdu2KZfNDcrtrLdIk7XGnQFYBWYDho/ORvXtn5XEePcL3tFpGjHCV3X3xrtDh7eZ+A==", + "dev": true, + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-packlist": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-9.0.0.tgz", + "integrity": "sha512-8qSayfmHJQTx3nJWYbbUmflpyarbLMBc6LCAjYsiGtXxDB68HaZpb8re6zeaLGxZzDuMdhsg70jryJe+RrItVQ==", + "dev": true, + "dependencies": { + "ignore-walk": "^7.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-10.0.0.tgz", + "integrity": "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==", + "dev": true, + "dependencies": { + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-18.0.2.tgz", + "integrity": "sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ==", + "dev": true, + "dependencies": { + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.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==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.4.1", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ordered-binary": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.3.tgz", + "integrity": "sha512-oGFr3T+pYdTGJ+YFEILMpS3es+GiIbs9h/XQrclBXUtd44ey7XwfsMzM31f64I1SQOawDoDr/D823kNCADI8TA==", + "dev": true, + "optional": true + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", + "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, + "node_modules/pacote": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-20.0.0.tgz", + "integrity": "sha512-pRjC5UFwZCgx9kUFDVM9YEahv4guZ1nSLqwmWiLUnDbGsjs+U5w7z6Uc8HNR1a6x8qnu5y9xtGE6D1uAuYz+0A==", + "dev": true, + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "devOptional": true, + "license": "MIT", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz", + "integrity": "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==", + "dev": true, + "dependencies": { + "entities": "^4.3.0", + "parse5": "^7.0.0", + "parse5-sax-parser": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-sax-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", + "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==", + "dev": true, + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/picomatch": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/piscina": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.7.0.tgz", + "integrity": "sha512-b8hvkpp9zS0zsfa939b/jXbe64Z2gZv0Ha7FYPNUiDIB1y2AtxcOZdfP8xN8HFjUaqQiT9gRlfjAsoL8vdJ1Iw==", + "dev": true, + "optionalDependencies": { + "@napi-rs/nice": "^1.0.1" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dev": true, + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "dev": true, + "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.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-loader": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cosmiconfig": "^9.0.0", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/punycode": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qjobs": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.9" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-parser": { + "version": "2.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/regexpu-core": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dev": true, + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.8", + "dev": true, + "license": "MIT", + "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-url-loader": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/resolve-url-loader/node_modules/loader-utils": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true + }, + "node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.26.0.tgz", + "integrity": "sha512-ilcl12hnWonG8f+NxU6BlgysVA0gvY2l8N0R84S1HcINbW20bvwuCngJkkInV6LXhwRpucsW5k1ovDwEdBVrNg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.26.0", + "@rollup/rollup-android-arm64": "4.26.0", + "@rollup/rollup-darwin-arm64": "4.26.0", + "@rollup/rollup-darwin-x64": "4.26.0", + "@rollup/rollup-freebsd-arm64": "4.26.0", + "@rollup/rollup-freebsd-x64": "4.26.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.26.0", + "@rollup/rollup-linux-arm-musleabihf": "4.26.0", + "@rollup/rollup-linux-arm64-gnu": "4.26.0", + "@rollup/rollup-linux-arm64-musl": "4.26.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.26.0", + "@rollup/rollup-linux-riscv64-gnu": "4.26.0", + "@rollup/rollup-linux-s390x-gnu": "4.26.0", + "@rollup/rollup-linux-x64-gnu": "4.26.0", + "@rollup/rollup-linux-x64-musl": "4.26.0", + "@rollup/rollup-win32-arm64-msvc": "4.26.0", + "@rollup/rollup-win32-ia32-msvc": "4.26.0", + "@rollup/rollup-win32-x64-msvc": "4.26.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.80.7", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.7.tgz", + "integrity": "sha512-MVWvN0u5meytrSjsU7AWsbhoXi1sc58zADXFllfZzbsBT1GHjjar6JwBINYPRrkx/zqnQ6uqbQuHgE95O+C+eQ==", + "dev": true, + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass-loader": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.3.tgz", + "integrity": "sha512-gosNorT1RCkuCMyihv6FBRR7BMV06oKRAs+l4UMp1mlcVg9rWN6KMmUj3igjQwmYys4mDP3etEYJgiHRbgHCHA==", + "dev": true, + "dependencies": { + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sass/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sax": { + "version": "1.4.1", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.6.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "license": "MIT" + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "license": "MIT", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/sigstore": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-3.0.0.tgz", + "integrity": "sha512-PHMifhh3EN4loMcHCz6l3v/luzgT3za+9f8subGgeMNjbJjzH4Ij/YoX3Gvu+kaouJRIlVdTHHCREADYf+ZteA==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/sign": "^3.0.0", + "@sigstore/tuf": "^3.0.0", + "@sigstore/verify": "^2.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socket.io": { + "version": "4.7.5", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.5.2", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "~4.3.4", + "ws": "~8.11.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "dev": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" + } + }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "dev": true + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, + "node_modules/ssri": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz", + "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "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==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-observable": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "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/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==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/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==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/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==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "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==", + "dev": true + }, + "node_modules/terser": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", + "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "dev": true, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tree-dump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", + "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/tuf-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-3.0.1.tgz", + "integrity": "sha512-+68OP1ZzSF84rTckf3FA95vJ1Zlx/uaXyiiKyPd1pA4rZNkpEvDAKmsu1xUSmbF/chCRYgZ6UZkDwC7PmzmAyA==", + "dev": true, + "dependencies": { + "@tufjs/models": "3.0.1", + "debug": "^4.3.6", + "make-fetch-happen": "^14.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/tuf-js/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/tuf-js/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-assert": { + "version": "1.0.9", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.38", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "dev": true, + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unique-filename": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz", + "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==", + "dev": true, + "dependencies": { + "unique-slug": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/unique-slug": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz", + "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "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.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.0.tgz", + "integrity": "sha512-d7KLgL1LD3U3fgnvWEY1cQXoO/q6EQ1BSz48Sa149V/5zVTAbgmZIpyI8TRi6U9/JNyeYLlTKsEMPtLC27RFUg==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "5.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.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": "*", + "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 + } + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "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" + } + }, + "node_modules/void-elements": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true, + "optional": true + }, + "node_modules/webpack": { + "version": "5.96.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.96.1.tgz", + "integrity": "sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "dev": true, + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.1.0.tgz", + "integrity": "sha512-aQpaN81X6tXie1FoOB7xlMfCsN19pSvRAeYUHOdFWOlhpQ/LlbfTqYwwmEDFV0h8GGuqmCmKmT+pxcUV/Nt2gQ==", + "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.19.2", + "graceful-fs": "^4.2.6", + "html-entities": "^2.4.0", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-subresource-integrity": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "typed-assert": "^1.0.8" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", + "webpack": "^5.12.0" + }, + "peerDependenciesMeta": { + "html-webpack-plugin": { + "optional": true + } + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.11.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xhr2": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.2.1.tgz", + "integrity": "sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zone.js": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.0.tgz", + "integrity": "sha512-9oxn0IIjbCZkJ67L+LkhYWRyAy7axphb3VgE2MBDlOqnmHMPWGYMxJxBYFueFq/JGY2GMwS0rU+UCLunEmy5UA==" + } + } +} diff --git a/examples/universal/package.json b/examples/universal/package.json new file mode 100644 index 00000000..fffedc13 --- /dev/null +++ b/examples/universal/package.json @@ -0,0 +1,49 @@ +{ + "name": "angular-modal-gallery-universal-demo", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "npm run build:dev", + "build:dev": "ng build --configuration development", + "build:prod": "ng build --configuration production", + "watch": "ng build --watch --configuration development", + "test": "ng test", + "serve:ssr": "node dist/universal/server/server.mjs" + }, + "private": true, + "dependencies": { + "@angular/animations": "^19.0.5", + "@angular/cdk": "^19.0.4", + "@angular/common": "^19.0.5", + "@angular/compiler": "^19.0.5", + "@angular/core": "^19.0.5", + "@angular/forms": "^19.0.5", + "@angular/platform-browser": "^19.0.5", + "@angular/platform-browser-dynamic": "^19.0.5", + "@angular/platform-server": "^19.0.5", + "@angular/router": "^19.0.5", + "@angular/ssr": "^19.0.6", + "@fortawesome/fontawesome-svg-core": "^6.7.2", + "@fortawesome/free-solid-svg-icons": "^6.7.2", + "express": "^4.18.2", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^19.0.6", + "@angular/cli": "~19.0.6", + "@angular/compiler-cli": "^19.0.5", + "@types/express": "^4.17.17", + "@types/jasmine": "~5.1.0", + "@types/node": "^18.18.0", + "jasmine-core": "~5.1.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.6.3" + } +} diff --git a/examples/universal/src/app/app-routing.module.ts b/examples/universal/src/app/app-routing.module.ts new file mode 100644 index 00000000..20be26e4 --- /dev/null +++ b/examples/universal/src/app/app-routing.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { ModalGalleryExampleComponent } from './modal-gallery/modal-gallery.component'; +import { PlainGalleryExampleComponent } from './plain-gallery/plain-gallery.component'; +import { CarouselExampleComponent } from './carousel/carousel.component'; +import { HomeComponent } from './home/home.component'; + +const routes: Routes = [ + { path: '', component: HomeComponent }, + { path: 'carousel', component: CarouselExampleComponent }, + { path: 'modal', component: ModalGalleryExampleComponent }, + { path: 'plain', component: PlainGalleryExampleComponent } +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes)], + exports: [RouterModule] +}) +export class AppRoutingModule {} diff --git a/examples/universal/src/app/app.component.html b/examples/universal/src/app/app.component.html new file mode 100644 index 00000000..27bca28a --- /dev/null +++ b/examples/universal/src/app/app.component.html @@ -0,0 +1,59 @@ + + +

+ + + +

+
+ + +
+

A special thank to all authors of icons used in this library:

+ +
+ +
+

A special thanks to all authors of spinners used in this library:

+ +
diff --git a/examples/universal/src/app/app.component.scss b/examples/universal/src/app/app.component.scss new file mode 100644 index 00000000..e06277ac --- /dev/null +++ b/examples/universal/src/app/app.component.scss @@ -0,0 +1,47 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + + +#main-title { + text-align: center; + width: 100%; +} + +#menu { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + + > .menu-item { + margin-left: 10px; + } +} + +.copyright { + text-align: center; +} + +.margin { + margin-left: 15px; + margin-right: 15px; +} diff --git a/examples/universal/src/app/app.component.ts b/examples/universal/src/app/app.component.ts new file mode 100644 index 00000000..17a818a5 --- /dev/null +++ b/examples/universal/src/app/app.component.ts @@ -0,0 +1,33 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component } from '@angular/core'; + +@Component({ + selector: 'ks-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'], + standalone: false +}) +export class AppComponent {} diff --git a/examples/universal/src/app/app.module.server.ts b/examples/universal/src/app/app.module.server.ts new file mode 100644 index 00000000..795380cd --- /dev/null +++ b/examples/universal/src/app/app.module.server.ts @@ -0,0 +1,14 @@ +import { NgModule } from '@angular/core'; +import { ServerModule } from '@angular/platform-server'; + +import { AppModule } from './app.module'; +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ + AppModule, + ServerModule, + ], + bootstrap: [AppComponent], +}) +export class AppServerModule {} diff --git a/examples/universal/src/app/app.module.ts b/examples/universal/src/app/app.module.ts new file mode 100644 index 00000000..31d2e9ea --- /dev/null +++ b/examples/universal/src/app/app.module.ts @@ -0,0 +1,73 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { BrowserModule, provideClientHydration } from '@angular/platform-browser'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; + +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; +import { CarouselExampleComponent } from './carousel/carousel.component'; +import { PlainGalleryExampleComponent } from './plain-gallery/plain-gallery.component'; +import { ModalGalleryExampleComponent } from './modal-gallery/modal-gallery.component'; +import { NavbarComponent } from './navbar/navbar.component'; +import { HomeComponent } from './home/home.component'; +import { IntroHeaderComponent } from './intro-header/intro-header.component'; + +// ********************** angular-modal-gallery ***************************** +import { GalleryModule } from '@ks89/angular-modal-gallery'; // <----------------- angular-modal-gallery library import +// ************************************************************************** + +// ************************ optional font-awesome 5 ************************ +// to install use both `npm i --save @fortawesome/fontawesome-svg-core` and `npm i --save @fortawesome/free-solid-svg-icons` +import { library, dom } from '@fortawesome/fontawesome-svg-core'; +import { faExternalLinkAlt, faPlus, faTimes, faDownload } from '@fortawesome/free-solid-svg-icons'; +library.add(faExternalLinkAlt, faPlus, faTimes, faDownload); +dom.watch(); // Kicks off the process of finding tags and replacing with +// ************************************************************************* + +@NgModule({ + declarations: [ + AppComponent, + CarouselExampleComponent, + PlainGalleryExampleComponent, + ModalGalleryExampleComponent, + NavbarComponent, + HomeComponent, + IntroHeaderComponent + ], + imports: [ + BrowserModule, + FormsModule, + + AppRoutingModule, + + GalleryModule // <-------------------------------------------- @ks89/angular-modal-gallery module import + ], + providers: [ + provideClientHydration() + ], + bootstrap: [AppComponent] +}) +export class AppModule {} diff --git a/examples/universal/src/app/carousel/carousel.component.ts b/examples/universal/src/app/carousel/carousel.component.ts new file mode 100644 index 00000000..47f180e9 --- /dev/null +++ b/examples/universal/src/app/carousel/carousel.component.ts @@ -0,0 +1,567 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2021 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component } from '@angular/core'; + +import { AccessibilityConfig, CarouselLibConfig, Image, ImageEvent, ModalGalleryConfig, ModalGalleryRef, ModalGalleryService, ModalLibConfig } from '@ks89/angular-modal-gallery'; + +@Component({ + selector: 'ks-carousel-page', + templateUrl: './carousel.html', + styleUrls: ['./carousel.scss'], + standalone: false +}) +export class CarouselExampleComponent { + imageIndex = 1; + galleryId = 1; + autoPlay = true; + showArrows = true; + showDots = true; + + LIBCONFIG102: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: false + } + }; + LIBCONFIG103: CarouselLibConfig = { + carouselSlideInfinite: false + }; + LIBCONFIG104: CarouselLibConfig = { + carouselDotsConfig: { + visible: false + } + }; + LIBCONFIG105: CarouselLibConfig = { + carouselPlayConfig: { + autoPlay: false, + interval: 5000, + pauseOnHover: true + } + }; + LIBCONFIG106: CarouselLibConfig = { + carouselPlayConfig: { + autoPlay: true, + interval: 10000, + pauseOnHover: false + } + }; + LIBCONFIG107: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 7, + width: 'auto', + maxHeight: '100px' + } + }; + LIBCONFIG113: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 5 + }, + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + } + }; + LIBCONFIG114: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 5, + width: 'auto', + maxHeight: '100px' + }, + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: true + } + }; + LIBCONFIG115: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 5, + width: 'auto', + maxHeight: '100px' + }, + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: false, + modalGalleryEnable: false + } + }; + LIBCONFIG116: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 7, + clickable: false + } + }; + LIBCONFIG117: CarouselLibConfig = { + carouselImageConfig: { + invertSwipe: true + } + }; + LIBCONFIG118: CarouselLibConfig = { + carouselImageConfig: { + description: { + strategy: 2 + } + } + }; + LIBCONFIG119: CarouselLibConfig = { + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + }, + carouselPreviewsConfig: { + visible: true, + number: 5, + width: 'auto', + maxHeight: '200px' + } + }; + LIBCONFIG120: CarouselLibConfig = { + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + }, + carouselPreviewsConfig: { + visible: true, + number: 5, + width: 'auto', + maxHeight: '150px' + } + }; + LIBCONFIG121: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + breakpoints: { + xSmall: 50, + small: 60, + medium: 80, + large: 150, + xLarge: 180 + } + } + }; + LIBCONFIG122: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + breakpoints: { + xSmall: 50, + small: 60, + medium: 70, + large: 80, + xLarge: 100 + } + }, + carouselConfig: { + maxWidth: '500px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + } + }; + LIBCONFIG124: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + breakpoints: { + xSmall: 50, + small: 60, + medium: 70, + large: 80, + xLarge: 100 + } + }, + carouselConfig: { + maxWidth: '500px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + }, + carouselPlayConfig: { + autoPlay: false, + interval: 1, + pauseOnHover: true + } + }; + + imagesRect: Image[] = [ + new Image( + 0, + { + img: '/assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1' + }, + { + img: '/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', + title: 'First image title', + alt: 'First image alt', + ariaLabel: 'First image aria-label' + } + ), + new Image(1, { img: '/assets/images/gallery/pexels-photo-47223.jpeg' }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg' }), + new Image( + 2, + { + img: '/assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3', + title: 'Third image title', + alt: 'Third image alt', + ariaLabel: 'Third image aria-label' + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '/assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4', + title: 'Fourth image title (modal obj)', + alt: 'Fourth image alt (modal obj)', + ariaLabel: 'Fourth image aria-label (modal obj)' + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', + title: 'Fourth image title (plain obj)', + alt: 'Fourth image alt (plain obj)', + ariaLabel: 'Fourth image aria-label (plain obj)' + } + ), + new Image(4, { img: '/assets/images/gallery/pexels-photo-93750.jpeg' }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg' }), + new Image( + 5, + { + img: '/assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6' + }, + { img: '/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg' } + ), + new Image(6, { img: '/assets/images/gallery/pexels-photo-96947.jpeg' }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg' }) + ]; + + imagesRectWithSources: Image[] = [ + new Image( + 0, + { + img: '/assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/milan-pegasus-gallery-statue-480w.jpg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/milan-pegasus-gallery-statue-768w.jpg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/milan-pegasus-gallery-statue-1024w.jpg' } + ] + }, + { + img: '/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', + title: 'First image title', + alt: 'First image alt', + ariaLabel: 'First image aria-label' + } + ), + new Image(1, { img: '/assets/images/gallery/pexels-photo-47223.jpeg', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-47223-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-47223-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-47223-1024w.jpeg' } + ] }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg' }), + new Image( + 2, + { + img: '/assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3', + title: 'Third image title', + alt: 'Third image alt', + ariaLabel: 'Third image aria-label', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-52062-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-52062-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-52062-1024w.jpeg' } + ] + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '/assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4', + title: 'Fourth image title (modal obj)', + alt: 'Fourth image alt (modal obj)', + ariaLabel: 'Fourth image aria-label (modal obj)', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-66943-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-66943-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-66943-1024w.jpeg' } + ] + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', + title: 'Fourth image title (plain obj)', + alt: 'Fourth image alt (plain obj)', + ariaLabel: 'Fourth image aria-label (plain obj)' + } + ), + new Image(4, { img: '/assets/images/gallery/pexels-photo-93750.jpeg', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-93750-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-93750-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-93750-1024w.jpeg' } + ] }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg' }), + new Image( + 5, + { + img: '/assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-94420-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-94420-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-94420-1024w.jpeg' } + ] + }, + { img: '/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg' } + ), + new Image(6, { img: '/assets/images/gallery/pexels-photo-96947.jpeg', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-96947-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-96947-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-96947-1024w.jpeg' } + ] }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg' }) + ]; + + emptyImagesArray: Image[] = []; + + imagesRectNoTitles: Image[] = [ + new Image( + 0, + { img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', title: '' } + ), + new Image( + 1, + { img: '../assets/images/gallery/pexels-photo-47223.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg', title: '' } + ), + new Image( + 2, + { img: '../assets/images/gallery/pexels-photo-52062.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', title: '' } + ), + new Image( + 3, + { img: '../assets/images/gallery/pexels-photo-66943.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', title: '' } + ), + new Image( + 4, + { img: '../assets/images/gallery/pexels-photo-93750.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg', title: '' } + ), + new Image( + 5, + { img: '../assets/images/gallery/pexels-photo-94420.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg', title: '' } + ), + new Image( + 6, + { img: '../assets/images/gallery/pexels-photo-96947.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg', title: '' } + ) + ]; + + fallbackRectImages: Image[] = [ + new Image(0, { + // this file is not available so the browser returns an error + img: '../assets/images/gallery/UNEXISTING_IMG1.jpg', + // because the img above doesn't exists, the library will use this file + fallbackImg: '../assets/images/gallery/fallback-carousel1.jpg' + }), + new Image(1, { + img: '../assets/images/gallery/UNEXISTING_IMG2.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel2.jpg' + }), + new Image( + 2, + { + img: '../assets/images/gallery/UNEXISTING_IMG3.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel3.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG3.png', + fallbackImg: '../assets/images/gallery/fallback-carousel3.jpg' + } + ), + new Image(3, { + img: '../assets/images/gallery/UNEXISTING_IMG4.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel4.jpg' + }), + new Image( + 4, + { + img: '../assets/images/gallery/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel5.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel5.jpg' + } + ) + ]; + + accessibilityConfig: AccessibilityConfig = { + backgroundAriaLabel: 'CUSTOM Modal gallery full screen background', + backgroundTitle: 'CUSTOM background title', + + plainGalleryContentAriaLabel: 'CUSTOM Plain gallery content', + plainGalleryContentTitle: 'CUSTOM plain gallery content title', + + modalGalleryContentAriaLabel: 'CUSTOM Modal gallery content', + modalGalleryContentTitle: 'CUSTOM modal gallery content title', + + loadingSpinnerAriaLabel: 'CUSTOM The current image is loading. Please be patient.', + loadingSpinnerTitle: 'CUSTOM The current image is loading. Please be patient.', + + mainContainerAriaLabel: 'CUSTOM Current image and navigation', + mainContainerTitle: 'CUSTOM main container title', + mainPrevImageAriaLabel: 'CUSTOM Previous image', + mainPrevImageTitle: 'CUSTOM Previous image', + mainNextImageAriaLabel: 'CUSTOM Next image', + mainNextImageTitle: 'CUSTOM Next image', + + dotsContainerAriaLabel: 'CUSTOM Image navigation dots', + dotsContainerTitle: 'CUSTOM dots container title', + dotAriaLabel: 'CUSTOM Navigate to image number', + + previewsContainerAriaLabel: 'CUSTOM Image previews', + previewsContainerTitle: 'CUSTOM previews title', + previewScrollPrevAriaLabel: 'CUSTOM Scroll previous previews', + previewScrollPrevTitle: 'CUSTOM Scroll previous previews', + previewScrollNextAriaLabel: 'CUSTOM Scroll next previews', + previewScrollNextTitle: 'CUSTOM Scroll next previews', + + carouselContainerAriaLabel: 'Current image and navigation', + carouselContainerTitle: '', + carouselPrevImageAriaLabel: 'Previous image', + carouselPrevImageTitle: 'Previous image', + carouselNextImageAriaLabel: 'Next image', + carouselNextImageTitle: 'Next image', + carouselPreviewsContainerAriaLabel: 'Image previews', + carouselPreviewsContainerTitle: '', + carouselPreviewScrollPrevAriaLabel: 'Scroll previous previews', + carouselPreviewScrollPrevTitle: 'Scroll previous previews', + carouselPreviewScrollNextAriaLabel: 'Scroll next previews', + carouselPreviewScrollNextTitle: 'Scroll next previews' + }; + + constructor(private modalGalleryService: ModalGalleryService) {} + + addRandomImage(): void { + const imageToCopy: Image = this.imagesRect[Math.floor(Math.random() * this.imagesRect.length)]; + const newImage: Image = new Image(this.imagesRect.length - 1 + 1, imageToCopy.modal, imageToCopy.plain); + this.imagesRect = [...this.imagesRect, newImage]; + } + + onChangeAutoPlay(): void { + this.autoPlay = !this.autoPlay; + } + + onChangeShowArrows(): void { + this.showArrows = !this.showArrows; + } + + onChangeShowDots(): void { + this.showDots = !this.showDots; + } + + // output evets + onShow(event: ImageEvent): void { + console.log('show', event); + } + + onFirstImage(event: ImageEvent): void { + console.log('firstImage', event); + } + + onLastImage(event: ImageEvent): void { + console.log('lastImage', event); + } + + getLibConfig108(autoPlay: boolean, showArrows: boolean, showDots: boolean): CarouselLibConfig { + return { + carouselDotsConfig: { + visible: showDots + }, + carouselPlayConfig: { + autoPlay: autoPlay, + interval: 3000, + pauseOnHover: true + }, + carouselConfig: { + maxWidth: '100%', + maxHeight: '400px', + showArrows: showArrows, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + } + } as CarouselLibConfig; + } + + openModal(imageIndex: number, id: number): void { + const imageToShow: Image = this.imagesRect[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: this.imagesRect, + currentImage: imageToShow + } as ModalGalleryConfig) as ModalGalleryRef; + } +} diff --git a/examples/universal/src/app/carousel/carousel.html b/examples/universal/src/app/carousel/carousel.html new file mode 100644 index 00000000..ee04ac8c --- /dev/null +++ b/examples/universal/src/app/carousel/carousel.html @@ -0,0 +1,215 @@ +

Carousel

+
+ +

Basic examples

+
+
+

A1 - (id=100) - carousel example (minimal with all defaults) without content projection

+
+ +
+
+
+

A2 - (id=101) - carousel example (minimal with all defaults)

+
+ +
This is my projected content!
+
+
+
+
+

A3 - (id=102) - carousel example without previews

+
+ +
This is my projected content!
+
+
+
+
+

A4 - (id=103) - carousel example without infinite sliding

+
+ +
This is my projected content!
+
+
+
+
+

A5 - (id=104) - carousel example without dots

+
+ +
This is my projected content!
+
+
+
+
+

A6 - (id=105) - carousel example without auto-play (but all other playConfig properties have default values)

+
+ +
This is my projected content!
+
+
+
+
+

A7 - (id=106) - carousel example with a custom playConfig (10s of interval and pauseOnHover disabled)

+
+ +
This is my projected content!
+
+
+
+
+

A8 - (id=107) - carousel example with a custom previewConfig (7 previews with 'auto' width and 100px of height)

+
+ +
This is my projected content!
+
+
+
+
+

A9 - (id=108) - carousel example with buttons to enable/disable autoplay, arrows and other properties

+

Autoplay:

+

Show Arrows:

+

Show Dots:

+
+ +
This is my projected content!
+
+
+
+
+

A10 - (id=109) - carousel example (minimal with all defaults) with outputs

+
+ +
+
+
+

A11 - (id=110) - carousel example with fallback images when it's not possible to load normal images (to fix issue #194)

+
+ +
+
+
+

A12 - (id=111) - carousel example without title attribute on images

+
+ +
+
+
+

A13 - (id=112) - carousel example with an empty images array.

+

Carousel component doesn't support empty images arrays! To prevent runtime errors, you should use an *ngIf to remove the carousel when there are no images.

+
+ +
+
+
+ +

Examples with custom style

+
+

B1 - (id=113) - carousel example with fixed maxWidth (766px) and custom previews

+

By default, on bigger screen, previews will have height = 200px. If you want you can customize it or also change all breakpoint widths.

+
+ +
This is my projected content!
+
+
+
+
+

B2 - (id=114) - carousel example with fixed maxWidth (766px), custom previews and open modal on click

+
+ +
This is my projected content!
+
+
+
+
+

B3 - (id=115) - carousel example with fixed maxWidth (766px), custom previews and keyboard navigation disabled (for example left/right arrows)

+
+ +
This is my projected content!
+
+
+
+
+

B4 - (id=116) - carousel example with 7 images and unclickable previews

+
+ +
This is my projected content!
+
+
+
+
+ +

Examples with custom current image

+
+

C1 - (id=117) - carousel example with invert swipe on touchscreen devices

+
+ +
This is my projected content!
+
+
+
+
+

C2 - (id=118) - carousel example with description

+
+ +
This is my projected content!
+
+
+
+ + +

Examples with custom previews height

+

I know that these examples look bad, but the purpose is to show only how the library handles heights. + In both examples I didn't set breakpoints, so it will be used default values, but with the maxHeight specified

+

If F1, the maxHeight is 200px, but also the default breakpoints has 200px as maximum size, so the result will be very bad on bigger screen. + In F2, I'm using a smaller maxHeight, so previews won't be taller than 150px, despite the default breakpoints on bigger screens (200px).

+
+

F1 - (id=119) - carousel example with fixed maxWidth (766px) and custom previews (maxHeight 200px)

+
+ +
This is my projected content!
+
+
+
+
+

F2 - (id=120) - carousel example with fixed maxWidth (766px) and custom previews (maxHeight 150px)

+
+ +
This is my projected content!
+
+
+
+ + +

Examples with custom heights for previews (to try responsiveness)

+
+
+

G1 - (id=121) - carousel example (previews with different heights based on the window's width: xSmall: 50, small: 60, medium: 80, large: 150, xLarge: 180)

+
+ +
+
+
+

G2 - (id=122) - carousel example with fixed maxWidth (500px) (previews with different heights based on the window's width: xSmall: 50, small: 60, medium: 70, large: 80, xLarge: 100)

+
+ +
+
+

Examples using sources (to improve LCP)

+
+
+

H1 - (id=123) - carousel example (minimal with all defaults) without content projection - using sources

+
+ +
+
+

H2 - (id=124) - carousel example with fixed maxWidth (500px) (previews with different heights based on the window's width: xSmall: 50, small: 60, medium: 70, large: 80, xLarge: 100) - using sources

+
+ +
+
+
diff --git a/examples/universal/src/app/carousel/carousel.scss b/examples/universal/src/app/carousel/carousel.scss new file mode 100644 index 00000000..6945ffa3 --- /dev/null +++ b/examples/universal/src/app/carousel/carousel.scss @@ -0,0 +1,157 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2021 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +:host { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; +} + +section { + width: 100%; +} + +h2, h3, p { + margin-left: 20px; +} + +$text-color: #fff; +$background: rgba(0, 0, 0, .7); + +.my-app-custom-plain-container-row { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + .my-app-custom-image-row { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-column { + align-items: center; + display: flex; + flex-direction: column; + justify-content: flex-start; + + .my-app-custom-image-column { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-with-desc { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + figure { + margin: 0; + position: relative; + + img { + max-width: 100%; + height: auto; + cursor: pointer; + } + + figcaption { + background: rgba(0, 0, 0, .5); + color: #fff; + font-size: 85%; + padding: 5px; + position: absolute; + bottom: 3px; + left: 0; + right: 0; + } + } + + .description { + font-weight: bold; + text-align: center; + } + + .my-app-custom-image-with-desc { + height: auto; + margin-right: 2px; + width: 200px; + align-self: start; + } +} + +.more { + background: $background; + cursor: pointer; + color: $text-color; + padding-top: 4px; + height: 46px; + position: absolute; + text-align: center; + width: 50px; +} + + +.projected { + color: white; + font-weight: 600; + font-size: 24px; + text-align: center; + position: absolute; + top: 50%; + width: 100%; + pointer-events: none; +} + +.title { + margin-top: 40px; +} diff --git a/examples/universal/src/app/home/home.component.ts b/examples/universal/src/app/home/home.component.ts new file mode 100644 index 00000000..78439963 --- /dev/null +++ b/examples/universal/src/app/home/home.component.ts @@ -0,0 +1,33 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2021 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component } from '@angular/core'; + +@Component({ + selector: 'ks-home-page', + templateUrl: './home.html', + styleUrls: ['./home.scss'], + standalone: false +}) +export class HomeComponent {} diff --git a/examples/universal/src/app/home/home.html b/examples/universal/src/app/home/home.html new file mode 100644 index 00000000..f5ec1261 --- /dev/null +++ b/examples/universal/src/app/home/home.html @@ -0,0 +1,12 @@ + +
+ +
+

Welcome

+

This is the official live example of @ks89/angular-modal-gallery. + To get started quickly you can try and check the sourcecode of this example.

+

If you need the full documentation with all apis, this is the official documentation website.

+ +

The official documentation is available at ks89.github.io/angular-modal-gallery-2024-v13.github.io

+
+ diff --git a/examples/universal/src/app/home/home.scss b/examples/universal/src/app/home/home.scss new file mode 100644 index 00000000..a80478dc --- /dev/null +++ b/examples/universal/src/app/home/home.scss @@ -0,0 +1,26 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2021 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +.container { + margin-left: 15px; + margin-right: 15px; +} diff --git a/examples/universal/src/app/intro-header/intro-header.component.ts b/examples/universal/src/app/intro-header/intro-header.component.ts new file mode 100644 index 00000000..c2b1e55b --- /dev/null +++ b/examples/universal/src/app/intro-header/intro-header.component.ts @@ -0,0 +1,33 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { Component } from '@angular/core'; + +@Component({ + selector: 'ks-intro-header', + templateUrl: 'intro-header.html', + styleUrls: ['intro-header.scss'], + standalone: false +}) +export class IntroHeaderComponent {} diff --git a/examples/universal/src/app/intro-header/intro-header.html b/examples/universal/src/app/intro-header/intro-header.html new file mode 100644 index 00000000..94cdd372 --- /dev/null +++ b/examples/universal/src/app/intro-header/intro-header.html @@ -0,0 +1,8 @@ +
+ @ks89/angular-modal-gallery icon +

@ks89/angular-modal-gallery

+

Image gallery for Angular >=19

+

Currently v13

+
+
diff --git a/examples/universal/src/app/intro-header/intro-header.scss b/examples/universal/src/app/intro-header/intro-header.scss new file mode 100644 index 00000000..e0eeaf88 --- /dev/null +++ b/examples/universal/src/app/intro-header/intro-header.scss @@ -0,0 +1,73 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// search all occurrences in all code, also html, because it's everywhere +$color-primary: #101010; +$color-secondary: #9e9e9e; +$color-white: #FFF; +$color-black: #000; +$color-light-black: #343A40; +$color-code: #c100e0; +$color-url: #0060b7; +$color-warning: #880012; + +//$font-huge: 24px; +$font-big: 18px; +$font-middle: 14px; +$font-small: 12px; +$font-very-small: 10px; + +.intro-header { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + background-color: $color-primary; + background: linear-gradient(135deg, $color-primary, $color-secondary); + margin-top: 10px; + padding-bottom: 1px; + color: $color-white; + + h1 { + color: $color-white; + font-size: 3rem; + } +} + +.project-title { + margin-top: 20px; + font-size: 2.8rem; + text-align: center; +} + +img { + margin-top: 25px; + border-radius: 10px +} + +.lead { + font-size: 1rem; + text-align: center; + color: #d4d4d4; +} diff --git a/examples/universal/src/app/modal-gallery/libconfigs.ts b/examples/universal/src/app/modal-gallery/libconfigs.ts new file mode 100644 index 00000000..fdf8c729 --- /dev/null +++ b/examples/universal/src/app/modal-gallery/libconfigs.ts @@ -0,0 +1,583 @@ +import { + ButtonsStrategy, + ButtonType, + Description, + DescriptionStrategy, + KS_DEFAULT_BTN_CLOSE, + KS_DEFAULT_BTN_DELETE, + KS_DEFAULT_BTN_DOWNLOAD, + KS_DEFAULT_BTN_EXTURL, + KS_DEFAULT_BTN_FULL_SCREEN, + LoadingConfig, + LoadingType, + ModalLibConfig, + Size +} from '@ks89/angular-modal-gallery'; + +const DEFAULT_SIZE_PREVIEWS: Size = { + width: '100px', + height: 'auto' +}; + +// Examples A +export const LIBCONFIG_406: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: true, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +export const LIBCONFIG_407: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: false, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +export const LIBCONFIG_408: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: false, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +// Examples B +export const LIBCONFIG_500: ModalLibConfig = { + previewConfig: { + visible: false + }, + dotsConfig: { + visible: false + } +}; + +export const LIBCONFIG_501: ModalLibConfig = { + buttonsConfig: { + visible: false, + strategy: ButtonsStrategy.DEFAULT + }, + previewConfig: { + visible: false + }, + dotsConfig: { + visible: false + } +}; + +export const LIBCONFIG_502: ModalLibConfig = { + buttonsConfig: { + visible: false, + strategy: ButtonsStrategy.DEFAULT + }, + slideConfig: { + infinite: false, + sidePreviews: { + show: false, + size: DEFAULT_SIZE_PREVIEWS + } + }, + previewConfig: { + visible: false + }, + dotsConfig: { + visible: false + } +}; + +export const LIBCONFIG_503: ModalLibConfig = { + previewConfig: { + visible: true, + size: { + width: '90px', + height: 'auto' + } + } +}; + +export const LIBCONFIG_504: ModalLibConfig = { + enableCloseOutside: false +}; + +export const LIBCONFIG_505: ModalLibConfig = { + currentImageConfig: { downloadable: false }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.DEFAULT + } +}; + +export const LIBCONFIG_506: ModalLibConfig = { + currentImageConfig: { downloadable: true }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.DEFAULT + } +}; + +export const LIBCONFIG_507: ModalLibConfig = { + currentImageConfig: { downloadable: true }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.SIMPLE + } +}; + +export const LIBCONFIG_508: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: false, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +export const LIBCONFIG_509: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: true, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +export const LIBCONFIG_510: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: false, + type: LoadingType.STANDARD + } + } +}; +export const LIBCONFIG_511: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.STANDARD + } + } +}; +export const LIBCONFIG_512: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.CIRCULAR + } + } +}; +export const LIBCONFIG_513: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.BARS + } + } +}; +export const LIBCONFIG_514: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.DOTS + } + } +}; +export const LIBCONFIG_515: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.CUBE_FLIPPING + } + } +}; +export const LIBCONFIG_516: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.CIRCLES + } + } +}; +export const LIBCONFIG_517: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.EXPLOSING_SQUARES + } + } +}; + +export const LIBCONFIG_518: ModalLibConfig = { + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.DEFAULT + } +}; +export const LIBCONFIG_519: ModalLibConfig = { + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.SIMPLE + } +}; +export const LIBCONFIG_520: ModalLibConfig = { + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.ADVANCED + } +}; +export const LIBCONFIG_521: ModalLibConfig = { + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.FULL + } +}; + +// default buttons but extUrl will open the link in a new tab instead of the current one +// this requires to specify all buttons manually (also if they are not really custom) +export const LIBCONFIG_522: ModalLibConfig = { + currentImageConfig: { downloadable: true }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.CUSTOM, + buttons: [ + { + className: 'ext-url-image', + type: ButtonType.EXTURL, + extUrlInNewTab: true // <--- this is the important thing to understand this example + }, + { + className: 'download-image', + type: ButtonType.DOWNLOAD + }, + { + className: 'close-image', + type: ButtonType.CLOSE + } + ] + } +}; + +export const LIBCONFIG_523: ModalLibConfig = { + currentImageConfig: { + downloadable: true + }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.CUSTOM, + buttons: [ + // KS_DEFAULT_BTN_ROTATE, + KS_DEFAULT_BTN_FULL_SCREEN, + KS_DEFAULT_BTN_DELETE, + KS_DEFAULT_BTN_EXTURL, + KS_DEFAULT_BTN_DOWNLOAD, + KS_DEFAULT_BTN_CLOSE + ] + } +}; + +export const LIBCONFIG_524: ModalLibConfig = { + currentImageConfig: { + downloadable: true + }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.CUSTOM, + buttons: [ + { + className: 'fas fa-plus white', + type: ButtonType.CUSTOM, + ariaLabel: 'custom plus aria label', + title: 'custom plus title', + fontSize: '20px' + }, + { + className: 'fas fa-times white', + type: ButtonType.CLOSE, + ariaLabel: 'custom close aria label', + title: 'custom close title', + fontSize: '20px' + }, + { + className: 'fas fa-download white', + type: ButtonType.DOWNLOAD, + ariaLabel: 'custom download aria label', + title: 'custom download title', + fontSize: '20px' + }, + { + className: 'fas fa-external-link-alt white', + type: ButtonType.EXTURL, + ariaLabel: 'custom exturl aria label', + title: 'custom exturl title', + fontSize: '20px' + } + ] + } +}; + +export const LIBCONFIG_525: ModalLibConfig = { + previewConfig: { + visible: true, + mobileVisible: true + } +}; + +// Examples C +export const LIBCONFIG_600: ModalLibConfig = { + keyboardConfig: { + esc: 'KeyQ', + left: 'ArrowDown', + right: 'ArrowUp' + } +}; + +export const LIBCONFIG_601: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + imageText: 'Look this image ', + numberSeparator: ' of ', + beforeTextDescription: ' => ' + } + } +}; + +export const LIBCONFIG_602: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.HIDE_IF_EMPTY, + imageText: 'Look this image ', + numberSeparator: ' of ', + beforeTextDescription: ' => ' + } + } +}; + +export const LIBCONFIG_603: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_HIDDEN, + // you should build this value programmatically with the result of (show)="..()" event + customFullDescription: 'Custom description of the current visible image' + // if customFullDescription !== undefined, all other fields will be ignored + // imageText: '', + // numberSeparator: '', + // beforeTextDescription: '', + } + } +}; + +export const LIBCONFIG_604: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + // you should build this value programmatically with the result of (show)="..()" event + customFullDescription: 'Custom description of the current visible image' + // if customFullDescription !== undefined, all other fields will be ignored + // imageText: '', + // numberSeparator: '', + // beforeTextDescription: '', + } + } +}; + +export const LIBCONFIG_605: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + imageText: 'Look this image ', + numberSeparator: ' of ', + beforeTextDescription: ' => ' + } + } +}; + +export const LIBCONFIG_606: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + imageText: 'Look this image ', + numberSeparator: ' of ', + beforeTextDescription: ' => ', + style: { + bgColor: 'rgba(255,0,0,.5)', + textColor: 'blue', + marginTop: '3px', + marginBottom: '0px', + marginLeft: '5px', + marginRight: '5px', + position: 'absolute', + top: '0px', + height: '25px' + // be careful to use width, in particular with % values + } + } + } +}; + +export const LIBCONFIG_607: ModalLibConfig = { + previewConfig: { + visible: true, + number: 1 + } +}; + +export const LIBCONFIG_608: ModalLibConfig = { + previewConfig: { + visible: true, + number: 5 + } +}; + +export const LIBCONFIG_609: ModalLibConfig = { + previewConfig: { + visible: true, + arrows: false + } +}; + +export const LIBCONFIG_610: ModalLibConfig = { + previewConfig: { + visible: true, + clickable: false + } +}; + +export const LIBCONFIG_611: ModalLibConfig = { + previewConfig: { + visible: true, + size: { width: '30px', height: '30px' } + } +}; + +export const LIBCONFIG_612: ModalLibConfig = { + accessibilityConfig: { + backgroundAriaLabel: 'CUSTOM Modal gallery full screen background', + backgroundTitle: 'CUSTOM background title', + + plainGalleryContentAriaLabel: 'CUSTOM Plain gallery content', + plainGalleryContentTitle: 'CUSTOM plain gallery content title', + + modalGalleryContentAriaLabel: 'CUSTOM Modal gallery content', + modalGalleryContentTitle: 'CUSTOM modal gallery content title', + + loadingSpinnerAriaLabel: 'CUSTOM The current image is loading. Please be patient.', + loadingSpinnerTitle: 'CUSTOM The current image is loading. Please be patient.', + + mainContainerAriaLabel: 'CUSTOM Current image and navigation', + mainContainerTitle: 'CUSTOM main container title', + mainPrevImageAriaLabel: 'CUSTOM Previous image', + mainPrevImageTitle: 'CUSTOM Previous image', + mainNextImageAriaLabel: 'CUSTOM Next image', + mainNextImageTitle: 'CUSTOM Next image', + + dotsContainerAriaLabel: 'CUSTOM Image navigation dots', + dotsContainerTitle: 'CUSTOM dots container title', + dotAriaLabel: 'CUSTOM Navigate to image number', + + previewsContainerAriaLabel: 'CUSTOM Image previews', + previewsContainerTitle: 'CUSTOM previews title', + previewScrollPrevAriaLabel: 'CUSTOM Scroll previous previews', + previewScrollPrevTitle: 'CUSTOM Scroll previous previews', + previewScrollNextAriaLabel: 'CUSTOM Scroll next previews', + previewScrollNextTitle: 'CUSTOM Scroll next previews', + + carouselContainerAriaLabel: 'Current image and navigation', + carouselContainerTitle: '', + carouselPrevImageAriaLabel: 'Previous image', + carouselPrevImageTitle: 'Previous image', + carouselNextImageAriaLabel: 'Next image', + carouselNextImageTitle: 'Next image', + carouselPreviewsContainerAriaLabel: 'Image previews', + carouselPreviewsContainerTitle: '', + carouselPreviewScrollPrevAriaLabel: 'Scroll previous previews', + carouselPreviewScrollPrevTitle: 'Scroll previous previews', + carouselPreviewScrollNextAriaLabel: 'Scroll next previews', + carouselPreviewScrollNextTitle: 'Scroll next previews' + } +}; + +export const LIBCONFIG_613: ModalLibConfig = { + currentImageConfig: { + navigateOnClick: false + } +}; + +// Examples D +export const LIBCONFIG_701: ModalLibConfig = { + currentImageConfig: { + downloadable: true + }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.SIMPLE + } +}; + +export const LIBCONFIG_702: ModalLibConfig = { + currentImageConfig: { + invertSwipe: true + } +}; + +export const LIBCONFIG_703: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: true, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +// Examples E +export const LIBCONFIG_800: ModalLibConfig = { + slideConfig: { + playConfig: { + autoPlay: true, + interval: 5000, + pauseOnHover: true + } + } +}; + +export const LIBCONFIG_801: ModalLibConfig = { + slideConfig: { + infinite: true, + playConfig: { + autoPlay: true, + interval: 5000, + pauseOnHover: false + } + } +}; + +export const LIBCONFIG_802: ModalLibConfig = { + slideConfig: { + playConfig: { + autoPlay: true, + interval: 1000, + pauseOnHover: false + } + } +}; + +// Examples F +export const LIBCONFIG_900: ModalLibConfig = { + slideConfig: { + infinite: false + }, + currentImageConfig: { + loadingConfig: { enable: true, type: LoadingType.STANDARD } as LoadingConfig, + description: { strategy: DescriptionStrategy.ALWAYS_VISIBLE } as Description + } +}; diff --git a/examples/universal/src/app/modal-gallery/modal-gallery.component.ts b/examples/universal/src/app/modal-gallery/modal-gallery.component.ts new file mode 100644 index 00000000..ce7c5f5e --- /dev/null +++ b/examples/universal/src/app/modal-gallery/modal-gallery.component.ts @@ -0,0 +1,763 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2021 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { TemplateRef } from '@angular/core'; +import { ViewChild } from '@angular/core'; +import { Component, OnDestroy } from '@angular/core'; +import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; + +import { + Action, + ButtonEvent, + ButtonType, + Image, + ImageModalEvent, + ModalGalleryService, + ModalGalleryRef, + ModalGalleryConfig, + ModalLibConfig +} from '@ks89/angular-modal-gallery'; +import { Subscription } from 'rxjs'; + +import * as libConfigs from './libconfigs'; + +@Component({ + selector: 'ks-modal-gallery-page', + templateUrl: './modal-gallery.html', + styleUrls: ['./modal-gallery.scss'], + standalone: false +}) +export class ModalGalleryExampleComponent implements OnDestroy { + /** + * A custom template to illustrate the customization of previews rendering. + */ + @ViewChild('previewsTemplate') + previewsTemplate?: TemplateRef; + + imageIndex = 0; + galleryId = 1; + isPlaying = true; + // Examples A + CONFIG406: ModalLibConfig = libConfigs.LIBCONFIG_406; + CONFIG407: ModalLibConfig = libConfigs.LIBCONFIG_407; + CONFIG408: ModalLibConfig = libConfigs.LIBCONFIG_408; + // Examples B + CONFIG500: ModalLibConfig = libConfigs.LIBCONFIG_500; + CONFIG501: ModalLibConfig = libConfigs.LIBCONFIG_501; + CONFIG502: ModalLibConfig = libConfigs.LIBCONFIG_502; + CONFIG503: ModalLibConfig = libConfigs.LIBCONFIG_503; + CONFIG504: ModalLibConfig = libConfigs.LIBCONFIG_504; + CONFIG505: ModalLibConfig = libConfigs.LIBCONFIG_505; + CONFIG506: ModalLibConfig = libConfigs.LIBCONFIG_506; + CONFIG507: ModalLibConfig = libConfigs.LIBCONFIG_507; + CONFIG508: ModalLibConfig = libConfigs.LIBCONFIG_508; + CONFIG509: ModalLibConfig = libConfigs.LIBCONFIG_509; + CONFIG510: ModalLibConfig = libConfigs.LIBCONFIG_510; + CONFIG511: ModalLibConfig = libConfigs.LIBCONFIG_511; + CONFIG512: ModalLibConfig = libConfigs.LIBCONFIG_512; + CONFIG513: ModalLibConfig = libConfigs.LIBCONFIG_513; + CONFIG514: ModalLibConfig = libConfigs.LIBCONFIG_514; + CONFIG515: ModalLibConfig = libConfigs.LIBCONFIG_515; + CONFIG516: ModalLibConfig = libConfigs.LIBCONFIG_516; + CONFIG517: ModalLibConfig = libConfigs.LIBCONFIG_517; + CONFIG518: ModalLibConfig = libConfigs.LIBCONFIG_518; + CONFIG519: ModalLibConfig = libConfigs.LIBCONFIG_519; + CONFIG520: ModalLibConfig = libConfigs.LIBCONFIG_520; + CONFIG521: ModalLibConfig = libConfigs.LIBCONFIG_521; + CONFIG522: ModalLibConfig = libConfigs.LIBCONFIG_522; + CONFIG523: ModalLibConfig = libConfigs.LIBCONFIG_523; + CONFIG524: ModalLibConfig = libConfigs.LIBCONFIG_524; + CONFIG525: ModalLibConfig = libConfigs.LIBCONFIG_525; + // Examples C + CONFIG600: ModalLibConfig = libConfigs.LIBCONFIG_600; + CONFIG601: ModalLibConfig = libConfigs.LIBCONFIG_601; + CONFIG602: ModalLibConfig = libConfigs.LIBCONFIG_602; + CONFIG603: ModalLibConfig = libConfigs.LIBCONFIG_603; + CONFIG604: ModalLibConfig = libConfigs.LIBCONFIG_604; + CONFIG605: ModalLibConfig = libConfigs.LIBCONFIG_605; + CONFIG606: ModalLibConfig = libConfigs.LIBCONFIG_606; + CONFIG607: ModalLibConfig = libConfigs.LIBCONFIG_607; + CONFIG608: ModalLibConfig = libConfigs.LIBCONFIG_608; + CONFIG609: ModalLibConfig = libConfigs.LIBCONFIG_609; + CONFIG610: ModalLibConfig = libConfigs.LIBCONFIG_610; + CONFIG611: ModalLibConfig = libConfigs.LIBCONFIG_611; + CONFIG612: ModalLibConfig = libConfigs.LIBCONFIG_612; + CONFIG613: ModalLibConfig = libConfigs.LIBCONFIG_613; + // Examples D + CONFIG701: ModalLibConfig = libConfigs.LIBCONFIG_701; + CONFIG702: ModalLibConfig = libConfigs.LIBCONFIG_702; + CONFIG703: ModalLibConfig = libConfigs.LIBCONFIG_703; + // Examples E + CONFIG800: ModalLibConfig = libConfigs.LIBCONFIG_800; + CONFIG801: ModalLibConfig = libConfigs.LIBCONFIG_801; + CONFIG802: ModalLibConfig = libConfigs.LIBCONFIG_802; + // Example F + CONFIG900: ModalLibConfig = libConfigs.LIBCONFIG_900; + + images: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: '../assets/images/gallery/img2.jpg', + description: 'Description 2' + }), + new Image( + 2, + { + img: '../assets/images/gallery/img3.jpg', + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new Image(3, { + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new Image(4, { img: '../assets/images/gallery/img5.jpg' }, { img: '../assets/images/gallery/thumbs/img5.jpg' }) + ]; + + emptyImagesArray: Image[] = []; + + imagesRectNoTitles: Image[] = [ + new Image( + 0, + { img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', title: '' } + ), + new Image( + 1, + { img: '../assets/images/gallery/pexels-photo-47223.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg', title: '' } + ), + new Image( + 2, + { img: '../assets/images/gallery/pexels-photo-52062.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', title: '' } + ), + new Image( + 3, + { img: '../assets/images/gallery/pexels-photo-66943.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', title: '' } + ), + new Image( + 4, + { img: '../assets/images/gallery/pexels-photo-93750.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg', title: '' } + ), + new Image( + 5, + { img: '../assets/images/gallery/pexels-photo-94420.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg', title: '' } + ), + new Image( + 6, + { img: '../assets/images/gallery/pexels-photo-96947.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg', title: '' } + ) + ]; + + fallbackImages: Image[] = [ + new Image(0, { + // this file is not available so the browser returns an error + img: '../assets/images/gallery/UNEXISTING_IMG1.jpg', + // because the img above doesn't exists, the library will use this file + fallbackImg: '../assets/images/gallery/fallback1.jpg' + }), + new Image(1, { + img: '../assets/images/gallery/UNEXISTING_IMG2.jpg', + fallbackImg: '../assets/images/gallery/fallback2.jpg' + }), + new Image( + 2, + { + img: '../assets/images/gallery/UNEXISTING_IMG3.jpg', + fallbackImg: '../assets/images/gallery/fallback3.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG3.png', + fallbackImg: '../assets/images/gallery/fallback3.jpg' + } + ), + new Image(3, { + img: '../assets/images/gallery/UNEXISTING_IMG4.jpg', + fallbackImg: '../assets/images/gallery/fallback4.jpg' + }), + new Image( + 4, + { + img: '../assets/images/gallery/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback5.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback5.jpg' + } + ) + ]; + + // array of images (obviously with different id) where paths are the same. + // to prevent caching issues I have to append '?index'. + sameImages: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg?1', + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: '../assets/images/gallery/img1.jpg?2', + extUrl: 'http://www.google.com' + }), + new Image(2, { + img: '../assets/images/gallery/img1.jpg?3', + extUrl: 'http://www.google.com' + }) + ]; + + // example of a png converted into base64 using https://www.base64-image.de/ or other similar websites + base64String = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABN0lEQV' + + 'R4nO3SQQ2AQBDAwAVlaMEhCkAV' + + 'b2RcQmcU9NEZAAAAAOD/tvN675k5VoewxLOvLmAtA8QZIM4AcQaIM0CcAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4gwQZ4A4A8QZIM4AcQaIM0C' + + 'cAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4gwQZ4A4A8QZIM4AcQaIM0CcAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4g' + + 'wQZ4A4A8QZIM4AcQaIM0CcAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4gwQZ4A4A8QZIM4AcQaIM0CcAeIMEGeAOAPEGQAAAAAA4Pc+8asEoPPGq' + + 'xUAAAAASUVORK5CYII'; + + base64RedString = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAY1BMVEX/AAD/////WVn/+vr/qan/Nzf/ERH/2tr/s7P/KSn/' + + '7+//vr7/0ND/W1v/6+v/m5v/4+P/U1P/HR3/o6P/rq7/g4P/k5P/t7f/dXX/SEj/zMz/ZWX/h4f/bm7/amr/np7/yMhDG/2oAAAC8ElEQVR4nO3dC3KqQBCF4WkHERHFRyKIL/' + + 'a/ymDuVYMMFipTbbfnW8H5S4lQVGUMaWe4B3iHQvlQKB8K5UOhfCiUD4XyoVA+FJ7Myijd5dvBO9nmuzQqZ68X2mI9NO9suC7s84VxNuAO6GSQxU8VJvuQe3pn4T55uLDYcK9+' + + '0KZ4qDB574vPbej+HF2Fcc499km563p0FAbcQ18QdCi0B+6VLzk0fjtuC0dj7o0vGo/uF064B/agvFcYca/rRdReeOTe1pNjW6HkP6J1gbtQwzV4NnEVJtyrepU0C2M599ldhH' + + 'GjcMq9qWfT28KUe1Hv0nrhnHuPB/Na4YJ7jgeLv4UZ9xovsmuhXXKP8WJpL4Ur7i2erC6Fun4Kr8Jz4Rf3Em++/hdKf+htN/5XqOuGtC75LfzmnuHR96nQ6v2SVl9TWxVq/pKevq' + + 'aG1twjvFpXhTLeLz1rQMZyb/DMmhH3BM9GRudjxVVmtN51n62M1DdpXeVG2rveR22MxLe9jxgazfdsJ2Oj9en3THsfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + + 'AAAAAAAAAAAAAAgHba/+98+AFnI+g/30L/GSX6z5nRf1aQ/vOe9J/Zpf/cNf1n533A+Yf6z7DUfw6p/rNkVX9Nkw850/kDzuXWf7Y6ab37Xl0K7ZJ7ixdLeykknQ8YGV0LacG9xo' + + 'MF/S2cc8/xYF4rpJR7T+9SqhfSlHtRz6Z0Wxjr+lEM40ahstvThJqFNOFe1aMJuQop4N7Vm4DchXTkXtaTI7UVUsS9rRcRtRequBZLuldII+mPw+MR3S8ke+De+JKDvQ1qFMr+kx' + + 'o0cxyFFEt945bHjhpXYXV/I/HN8DBxtrgLiQpp74Y3RUtJW2H1Oe7l3IuHe/fnd7+wuh4zGe+lBpnr+utSWLHF+r0vyeG6aPw+PFT4a1ZG6S7fDt7JNt+lUTnrsL5LoWwolA+F8q' + + 'FQPhTKh0L5UCgfCuVDoXw/lnQz7dm7GjoAAAAASUVORK5CYII='; + base64GreenString = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAgMAAADQNkYNAAAADFBMVEUAAAAy/ysy/ysy/ysyTcibAAAAA3RSTlMA2r/af0d' + + 'WAAAAQUlEQVRo3u3YMREAMAzEsJAMyZJsMXy3XORdBFySJK3qxFXH1Y1DEARBEARBEARBEARBEARBkNmk436mvSRJ0o4eOKL2P81eyn8AAAAASUVORK5CYII='; + + base64Image: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.base64String); + base64RedImage: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.base64RedString); + base64GreenImage: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.base64GreenString); + + imagesBase64: Image[] = [ + new Image(0, { + img: this.base64Image, + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: this.base64GreenImage, + description: 'Description 2' + }), + new Image( + 2, + { + img: this.base64RedImage, + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + img: this.base64RedImage, + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ) + ]; + + imagesCustomDownloadFileName: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg', + downloadFileName: 'first-img.jpg' + }), + new Image(1, { + img: this.base64Image, + downloadFileName: 'second-img-base64.jpg' + }) + ]; + + imagesHtmlDescriptions: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: '../assets/images/gallery/img2.jpg', + description: '
  1. This is
  2. the description
  3. number
  4. 2
' + }), + new Image( + 2, + { + img: '../assets/images/gallery/img3.jpg', + description: '
  • Description
  • 3
', + extUrl: 'http://www.google.com' + }, + { + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new Image(3, { + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new Image(4, { img: '../assets/images/gallery/img5.jpg' }, { img: '../assets/images/gallery/thumbs/img5.jpg' }) + ]; + + imagesRect: Image[] = [ + new Image( + 0, + { + img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1' + }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg' } + ), + new Image(1, { img: '../assets/images/gallery/pexels-photo-47223.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg' }), + new Image( + 2, + { + img: '../assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3' + }, + { + img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '../assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4' + }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg' } + ), + new Image(4, { img: '../assets/images/gallery/pexels-photo-93750.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg' }), + new Image( + 5, + { + img: '../assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6' + }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg' } + ), + new Image(6, { img: '../assets/images/gallery/pexels-photo-96947.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg' }) + ]; + + imagesMixedSizes: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/pexels-photo-135230.png', + description: 'Description 1' + }), + new Image(1, { + img: '../assets/images/gallery/pexels-photo-547115.jpeg' + }), + new Image(2, { + img: '../assets/images/gallery/pexels-photo-556664.jpeg', + description: 'Description 3' + }), + new Image(3, { + img: '../assets/images/gallery/pexels-photo-787594.jpeg', + description: 'Description 4' + }), + new Image(4, { + img: '../assets/images/gallery/pexels-photo-803105.jpeg' + }) + ]; + + // example of images with small previews (they are different files) to show + // loading spinners + imagesForLoadingSpinner: Image[] = [ + new Image( + 0, + { + img: '../assets/images/loading-spinner-samples/pexels-photo-74506.jpg' + }, + { img: '../assets/images/loading-spinner-samples/pexels-photo-74506-thumb.jpg' } + ), + new Image( + 1, + { + img: '../assets/images/loading-spinner-samples/pexels-photo-106006.jpg' + }, + { img: '../assets/images/loading-spinner-samples/pexels-photo-106006-thumb.jpg' } + ), + new Image( + 2, + { + img: '../assets/images/loading-spinner-samples/pexels-photo-464336.jpg' + }, + { img: '../assets/images/loading-spinner-samples/pexels-photo-464336-thumb.jpg' } + ), + new Image( + 3, + { + img: '../assets/images/loading-spinner-samples/pexels-photo.jpg' + }, + { img: '../assets/images/loading-spinner-samples/pexels-photo-thumb.jpg' } + ), + new Image( + 4, + { + img: '../assets/images/loading-spinner-samples/traffic-highway-lights-night-56891.jpg' + }, + { img: '../assets/images/loading-spinner-samples/traffic-highway-lights-night-56891-thumb.jpg' } + ) + ]; + + // array with a single image inside (the first one) + singleImage: Image[] = [this.images[0]]; + + imagesInfiniteAutoAdd: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg?1', + extUrl: 'http://www.google.com' + }) + ]; + + private count = 0; + + // subscriptions to receive events from the gallery + // REMEMBER TO call unsubscribe(); in ngOnDestroy (see below) + private closeSubscription: Subscription | undefined; + private showSubscription: Subscription | undefined; + private firstImageSubscription: Subscription | undefined; + private lastImageSubscription: Subscription | undefined; + private hasDataSubscription: Subscription | undefined; + private buttonBeforeHookSubscription: Subscription | undefined; + private buttonAfterHookSubscription: Subscription | undefined; + + constructor(private modalGalleryService: ModalGalleryService, private sanitizer: DomSanitizer) {} + + // this variable is used only for example of auto navigation + // tslint:disable-next-line:no-any + private timeout: any; + + openModalWithAutoClose(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + + this.showSubscription = dialogRef.show$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - show$: ', event); + const galleryId: number = event.galleryId; + console.log(`onShowAutoCloseExample with id=${galleryId} action: ` + Action[event.action]); + console.log('onShowAutoCloseExample result:' + event.result); + console.log('Starting timeout of 3 seconds to close modal gallery automatically'); + // clear previous timeout + clearTimeout(this.timeout); + this.timeout = setTimeout(() => { + console.log('setTimeout end - closing gallery with id=' + galleryId); + this.modalGalleryService.close(galleryId, false); + }, 3000); + }); + } + + addRandomImage(): void { + // add to images array + const imageToCopy: Image = this.images[Math.floor(Math.random() * this.images.length)]; + const newImage: Image = new Image(this.images.length - 1 + 1, imageToCopy.modal, imageToCopy.plain); + this.images = [...this.images, newImage]; + // add also to imagesRect + const imageRectToCopy: Image = this.imagesRect[Math.floor(Math.random() * this.imagesRect.length)]; + const newImageRect: Image = new Image(this.imagesRect.length - 1 + 1, imageRectToCopy.modal, imageRectToCopy.plain); + this.imagesRect = [...this.imagesRect, newImageRect]; + // add also to imagesMixedSizes + const imageMixToCopy: Image = this.imagesMixedSizes[Math.floor(Math.random() * this.imagesMixedSizes.length)]; + const newImageMix: Image = new Image(this.imagesMixedSizes.length - 1 + 1, imageMixToCopy.modal, imageMixToCopy.plain); + this.imagesMixedSizes = [...this.imagesMixedSizes, newImageMix]; + } + + openModal(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + if(imagesArrayToUse.length === 0) { + console.error('Cannot open modal-gallery because images array cannot be empty'); + return; + } + if(imageIndex > imagesArrayToUse.length - 1) { + console.error('Cannot open modal-gallery because imageIndex must be valid'); + return; + } + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + } + + openModalWithOutputs(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.closeSubscription = dialogRef.close$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - close$: ', event); + }); + this.showSubscription = dialogRef.show$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - show$: ', event); + }); + this.firstImageSubscription = dialogRef.firstImage$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - firstImage$: ', event); + }); + this.lastImageSubscription = dialogRef.lastImage$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - lastImage$: ', event); + }); + this.hasDataSubscription = dialogRef.hasData$.subscribe((event: ImageModalEvent) => { + // angular-modal-gallery will emit this event if it will load successfully input images + console.log('OUTPUT - hasData$: ', event); + }); + this.buttonBeforeHookSubscription = dialogRef.buttonBeforeHook$.subscribe((event: ButtonEvent) => { + console.log('OUTPUT - buttonBeforeHook$: ', event); + if (!event || !event.button) { + return; + } + // Invoked after a click on a button, but before that the related + // action is applied. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + if (event.button.type === ButtonType.DELETE) { + // remove the current image and reassign all other to the array of images + console.log('delete in app with images count ' + this.images.length); + this.images = this.images.filter((val: Image) => event.image && val.id !== event.image.id); + } + }); + this.buttonAfterHookSubscription = dialogRef.buttonAfterHook$.subscribe((event: ButtonEvent) => { + if (!event || !event.button) { + return; + } + // Invoked after both a click on a button and its related action. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + }); + } + + openModalWithDeleteButton(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: [...imagesArrayToUse], + currentImage: Object.assign({}, imageToShow), + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.buttonBeforeHookSubscription = dialogRef.buttonBeforeHook$.subscribe((event: ButtonEvent) => { + console.log('OUTPUT - buttonBeforeHook$:', event); + if (!event || !event.button) { + return; + } + // Invoked after a click on a button, but before that the related + // action is applied. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + }); + this.buttonAfterHookSubscription = dialogRef.buttonAfterHook$.subscribe((event: ButtonEvent) => { + console.log('OUTPUT - buttonAfterHook$:', event); + if (!event || !event.button) { + return; + } + if (event.button.type === ButtonType.DELETE) { + // remove the current image and reassign all other to the array of images + this.images = this.images.filter((val: Image) => event.image && val.id !== event.image.id); + this.modalGalleryService.updateModalImages(this.images); + } + // Invoked after both a click on a button and its related action. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + }); + } + + openModalWithAddButton(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.buttonBeforeHookSubscription = dialogRef.buttonBeforeHook$.subscribe((event: ButtonEvent) => { + if (!event || !event.button) { + return; + } + // Invoked after a click on a button, but before that the related + // action is applied. + + if (event.button.type === ButtonType.CUSTOM) { + console.log('adding a new random image at the end'); + this.addRandomImage(); + setTimeout(() => { + this.modalGalleryService.updateModalImages(this.images); + }, 0); + } + }); + this.buttonAfterHookSubscription = dialogRef.buttonAfterHook$.subscribe((event: ButtonEvent) => { + console.log('OUTPUT - buttonAfterHook$:', event); + if (!event || !event.button) { + return; + } + // Invoked after both a click on a button and its related action. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + }); + } + + openModalWithAutoAdd(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.showSubscription = dialogRef.show$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - show$: ', event); + if (this.count !== 0) { + return; + } + const interval = setInterval(() => { + const imageToCopy: Image = this.images[Math.floor(Math.random() * this.images.length)]; + const newImage: Image = new Image(this.imagesInfiniteAutoAdd.length - 1 + 1, imageToCopy.modal, imageToCopy.plain); + newImage.modal.img += `?${this.imagesInfiniteAutoAdd.length + 1}`; + this.imagesInfiniteAutoAdd = [...this.imagesInfiniteAutoAdd, newImage]; + this.modalGalleryService.updateModalImages(this.imagesInfiniteAutoAdd); + this.count++; + if (this.count === 4) { + clearInterval(interval); + } + }, 2000); + }); + } + + openModalWithAutoUpdate(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.showSubscription = dialogRef.show$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - show$: ', event); + if (this.count !== 0) { + return; + } + const indexToRefresh = 1; + const image: Image = new Image(1, { + img: '../assets/images/gallery/img5.jpg', + description: 'Description 2 updated with imag5.jpg' + }); + + console.log('updating image at index ' + indexToRefresh + ', after 4 seconds'); + + // create the new array of images with the updated image inside + const newImages: Image[] = [...this.images]; + newImages[indexToRefresh] = image; + + setTimeout(() => { + this.modalGalleryService.updateModalImages(newImages); + console.log('image updated successfully!'); + }, 4000); + }); + } + + autoPlayButton(config: ModalLibConfig): boolean { + this.isPlaying = !this.isPlaying; + if (config && config.slideConfig && config.slideConfig.playConfig) { + config.slideConfig.playConfig.autoPlay = this.isPlaying; + } + return this.isPlaying; + } + + trackById(index: number, item: Image): number { + return item.id; + } + + openModalWithPreviewsTemplate(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + if(imagesArrayToUse.length === 0) { + console.error('Cannot open modal-gallery because images array cannot be empty'); + return; + } + if(imageIndex > imagesArrayToUse.length - 1) { + console.error('Cannot open modal-gallery because imageIndex must be valid'); + return; + } + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig, + previewsTemplate: this.previewsTemplate, + } as ModalGalleryConfig) as ModalGalleryRef; + } + + ngOnDestroy(): void { + // release resources to prevent memory leaks and unexpected behaviours + if (this.closeSubscription) { + this.closeSubscription.unsubscribe(); + } + if (this.showSubscription) { + this.showSubscription.unsubscribe(); + } + if (this.firstImageSubscription) { + this.firstImageSubscription.unsubscribe(); + } + if (this.lastImageSubscription) { + this.lastImageSubscription.unsubscribe(); + } + if (this.hasDataSubscription) { + this.hasDataSubscription.unsubscribe(); + } + if (this.buttonBeforeHookSubscription) { + this.buttonBeforeHookSubscription.unsubscribe(); + } + if (this.buttonAfterHookSubscription) { + this.buttonAfterHookSubscription.unsubscribe(); + } + } +} diff --git a/examples/universal/src/app/modal-gallery/modal-gallery.html b/examples/universal/src/app/modal-gallery/modal-gallery.html new file mode 100644 index 00000000..2a264c8b --- /dev/null +++ b/examples/universal/src/app/modal-gallery/modal-gallery.html @@ -0,0 +1,325 @@ +

Modal Gallery

+
+ +

If you want, you can add a random image to every example + +

+
+

Index to open:   

+
+
+

WARNING: remember to use always different ids across your application!!!

+
+
+
+

Minimal examples

+
+

A1 - (id=400) - Minimal demo - all defaults (images array)

+ +
+
+

A1bis - (id=401) - Minimal demo - all defaults with rect images (imagesRect array)

+ +
+
+

A1tris - (id=402) - Minimal demo - all defaults with images of different sizes (imagesMixedSizes array)

+ +
+
+

A2 - (id=403) - Minimal demo - listen for events

+

I added 'openModalWithOutputs()' public method to listen for events

+ +
+
+

A3 - (id=405) - Minimal demo - single image (singleImage array)

+ +
+
+

A4 - (id=406) - Minimal demo - single image with infinite sliding enabled (to fix issue #156)

+ +
+
+

A5 - (id=407) - Minimal demo - two images with infinite sliding enabled (to fix issue #156)

+ +
+
+

A6 - (id=408) - Minimal demo - three image with infinite sliding enabled (to fix issue #156)

+ +
+
+

A7 - (id=409) - Minimal demo - use fallback images when it's not possible to load normal images (to fix issue #194)

+ +
+
+
+
+

Simple examples

+
+

B1 - (id=500) - Simple demo - only current image and buttons (previews and dots are hidden)

+ +
+
+

B2 - (id=501) - Simple demo - only current image (buttons, previews and dots are hidden)

+ +
+
+

B3 - (id=502) - Simple demo - only current image (side previews, buttons, previews and dots are hidden)

+ +
+
+

B3bis - (id=503) - Simple demo - custom preview size

+ +
+
+

B4 - (id=504) - Simple demo - disable closeOutside

+ +
+
+

B5 - (id=505) - Simple demo - no downloadable at all

+ +
+
+

B6 - (id=506) - Simple demo - no download button (only with keyboard)

+ +
+
+

B7 - (id=507) - Simple demo - download with both button and keyboard

+ +
+
+

B8 - (id=508) - Simple demo - infinite sliding but NO side previews

+ +
+
+

B9 - (id=509) - Simple demo - infinite sliding and side previews

+ +
+
+

B10 - (id=510) - Simple demo - disable loading spinner

+ +
+
+

B11 - (id=511) - Simple demo - loading spinner of type Standard

+ +
+
+

B12 - (id=512) - Simple demo - loading spinner of type Circular

+ +
+
+

B13 - (id=513) - Simple demo - loading spinner of type Bars

+ +
+
+

B14 - (id=514) - Simple demo - loading spinner of type Dots

+ +
+
+

B15 - (id=515) - Simple demo - loading spinner of type Cube Flipping

+ +
+
+

B16 - (id=516) - Simple demo - loading spinner of type Circles

+ +
+
+

B17 - (id=517) - Simple demo - loading spinner of type Explosing Squares

+ +
+ +
+

B18 - (id=518) - Simple demo - buttons config DEFAULT strategy (only close)

+ +
+
+

B19 - (id=519) - Simple demo - buttons config SIMPLE strategy (close and download)

+ +
+
+

B20 - (id=520) - Simple demo - buttons config ADVANCED strategy (close, download and exturl in the current + tab)

+ +
+
+

B21 - (id=521) - Simple demo - buttons config FULL strategy (all buttons)

+

I added also 'openModalWithDeleteButton()' public method to support delete button

+ +
+
+

B22 - (id=522) - Simple demo - buttons config CUSTOM strategy with exturl in ANOTHER TAB ('_blank')

+ +
+
+

B23 - (id=523) - Simple demo - buttons config CUSTOM but with all default buttons already included in the library

+

I added also 'openModalWithDeleteButton()' public method to support delete button

+ +
+
+

B24 - (id=524) - Simple demo - buttons config CUSTOM strategy with Font Awesome 5

+

I added also 'openModalWithAddButton()' public method to support delete button

+
+ +
+
+

B25 - (id=525) - Previews visible on mobile screen

+

Added PreviewConfig.mobileVisible configuration param

+
+ +
+
+
+
+

Advanced examples

+
+

C1 - (id=600) - Advanced demo - custom keyboard ('up'/'down' arrows and 'q' to close)

+ +
+
+

C2 - (id=601) - Advanced demo - custom description always visible

+ +
+
+

C3 - (id=602) - Advanced demo - custom description hide if empty

+ +
+
+

C4 - (id=603) - Advanced demo - custom description always hidden

+ +
+
+

C5 - (id=604) - Advanced demo - custom FULL description always visible

+ +
+
+

C6 - (id=605) - Advanced demo - custom HTML description always visible

+ +
+
+

C7 - (id=606) - Advanced demo - custom description style (always visible)

+ +
+ +
+

C8 - (id=607) - Advanced demo - preview custom configuration with 1 image (clickable)

+ +
+ +
+

C9 - (id=608) - Advanced demo - preview custom configuration with 5 images (clickable)

+ +
+ +
+

C10 - (id=609) - Advanced demo - preview custom configuration without arrows (clickable)

+ +
+
+

C11 - (id=610) - Advanced demo - preview custom configuration not clickable

+ +
+
+

C12 - (id=611) - Advanced demo - preview custom configuration with custom size

+ +
+ +
+

C13 - (id=612) - Advanced demo - accessibility config

+ +
+ +
+

C14 - (id=613) - Advanced demo - disable clicks on current image in modal-image

+ +
+ +
+

C15 - (id=614) - Advanced demo - after 3 seconds it closes modal gallery automatically with galleryService close method

+

Attention: please check the console to understand what it's happening!

+

Timer will clear and restart every time you show another image!

+ +
+ +
+
+
+

Other examples

+
+

D1 - (id=700) - Other demo - base64 images

+ +
+ +
+

D2 - (id=701) - Other demo - custom file name, used when downloaded

+ +
+ +
+

D3 - (id=702) - Other demo - invert touchscreen swipe direction

+ +
+ +
+

D4 - (id=703) - Other demo - infinite sliding and automatic add of images when the gallery is visible

+ +
+ +
+

D5 - (id=704) - Other demo - automatic update of the second image (index=1) via gallery service (open the second image and wait some seconds to see the result)

+ +
+ +
+

D6 - (id=705) - Other demo - remove title attribute on images

+ +
+ +
+

D7 - (id=706) - Other demo - modal gallery with an empty images array

+ +
+ +
+
+
+

AutoPlay examples

+
+

E1 - (id=800) - AutoPlay demo - with interval=5000 and pauseOnHover enabled

+ +
+
+

E2 - (id=801) - AutoPlay demo - with interval=5000, pauseOnHover disabled and infinite is enabled

+ +
+
+

E3 - (id=802) - AutoPlay demo - with interval=1000 and pauseOnHover disabled

+

+ +
+ + +
+
+
+

Experimental examples*

+

* these will be either improved or removed in next versions

+
+

F1 - (id=900) - Experimental demo - infinite sliding with only one image to see if side arrows are hidden

+ +
+
+

F2 - (id=901) - Experimental demo - an array of Images with the same source file (different classes/ids and paths with appended '?imageIndex' to prevent caching issues)

+ +
+
+

F3 - (id=902) - Experimental demo - 'previews' rendering customization (via Angular templates)

+ +
+
{{preview?.modal?.description ?? ' '}}
+
+ +
+
+
+ +
+ diff --git a/examples/universal/src/app/modal-gallery/modal-gallery.scss b/examples/universal/src/app/modal-gallery/modal-gallery.scss new file mode 100644 index 00000000..333e66e4 --- /dev/null +++ b/examples/universal/src/app/modal-gallery/modal-gallery.scss @@ -0,0 +1,177 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2021 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +:host { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + margin-left: 20px; + margin-right: 20px; +} + +$text-color: #fff; +$background: rgba(0, 0, 0, .7); + +button { + background-color: #0060b7; + color: white; + height: 25px; + width: auto; + border: 0; + border-radius: 5px; + cursor: pointer; + + &:hover { + background-color: #0086ff; + } +} + +.my-app-custom-plain-container-row { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + .my-app-custom-image-row { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-column { + align-items: center; + display: flex; + flex-direction: column; + justify-content: flex-start; + + .my-app-custom-image-column { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-with-desc { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + figure { + margin: 0; + position: relative; + + img { + max-width: 100%; + height: auto; + cursor: pointer; + } + + figcaption { + background: rgba(0, 0, 0, .5); + color: #fff; + font-size: 85%; + padding: 5px; + position: absolute; + bottom: 3px; + left: 0; + right: 0; + } + } + + .description { + font-weight: bold; + text-align: center; + } + + .my-app-custom-image-with-desc { + height: auto; + margin-right: 2px; + width: 200px; + align-self: start; + } +} + +.more { + background: $background; + cursor: pointer; + color: $text-color; + padding-top: 4px; + height: 46px; + position: absolute; + text-align: center; + width: 50px; +} + + +.transcluded { + color: white; + font-weight: 600; + font-size: 24px; + text-align: center; + position: absolute; + top: 50%; + width: 100%; + pointer-events: none; +} + +.title { + margin-top: 40px; +} + +.preview-block { + margin-right: 10px; +} +.preview-description { + color: #fff; + margin-bottom: 3px; +} +.preview-description, +.preview-default { + text-align: center; +} diff --git a/examples/universal/src/app/navbar/navbar.component.ts b/examples/universal/src/app/navbar/navbar.component.ts new file mode 100644 index 00000000..7708d11a --- /dev/null +++ b/examples/universal/src/app/navbar/navbar.component.ts @@ -0,0 +1,63 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { Component } from '@angular/core'; +import { Router } from '@angular/router'; +import { BreakpointObserver } from '@angular/cdk/layout'; + +@Component({ + selector: 'ks-navbar', + templateUrl: 'navbar.html', + styleUrls: ['navbar.scss'], + standalone: false +}) +export class NavbarComponent { + navbarHeight = '56px'; + // path: string = PATH + '/assets/amg.svg'; + + collapsed = false; + + constructor(private router: Router, breakpointObserver: BreakpointObserver) { + breakpointObserver.observe(['(min-width: 990px)']).subscribe(result => { + if (result.matches) { + console.log('min width 990px'); + this.collapsed = false; + } + }); + } + + isNavItemActive(location: string): string { + return this.router.url.includes(location) ? 'active' : ''; + } + + onNavigateTo(path: string): void { + this.collapsed = false; + this.router.navigate([path]); + } + + onToggle(): void { + this.collapsed = !this.collapsed; + this.navbarHeight = this.collapsed ? '56px' : '150px'; + } +} diff --git a/examples/universal/src/app/navbar/navbar.html b/examples/universal/src/app/navbar/navbar.html new file mode 100644 index 00000000..f95de0c4 --- /dev/null +++ b/examples/universal/src/app/navbar/navbar.html @@ -0,0 +1,68 @@ + + + + + diff --git a/examples/universal/src/app/navbar/navbar.scss b/examples/universal/src/app/navbar/navbar.scss new file mode 100644 index 00000000..f8580359 --- /dev/null +++ b/examples/universal/src/app/navbar/navbar.scss @@ -0,0 +1,233 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +nav { + padding-top: 8px; + padding-bottom: 8px; + padding-left: 16px; + padding-right: 16px; +} + +ul { + margin-top: 0; + margin-bottom: 0; + padding-left: 0; +} + +nav.nav-expanded { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + background-color: #343A40; + padding-top: 8px; + padding-left: 16px; + padding-bottom: 8px; + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 10; + + > .navbar-hamburger { + display: none; + background-color: #343A40; + border-color: rgba(255, 255, 255, .1); + + @media screen and (max-width: 990px) { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + cursor: pointer; + padding-top: 4px; + padding-bottom: 4px; + padding-left: 12px; + padding-right: 12px; + } + } + + > .navbar-wrapper { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + + @media screen and (max-width: 990px) { + display: none; + } + + > .navbar-brand { + font-size: 16px; + color: #ffffff; + font-weight: 400; + margin-left: 8px; + margin-right: 8px; + cursor: pointer; + + > img { + border-radius: 3px + } + + &:hover { + color: #bdbdbd; + } + } + + > .navbar-nav { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + list-style: none; + + > .nav-item { + cursor: pointer; + color: #e2e2e2; + + > a.nav-link { + color: #b9b9b9; + font-size: 14px; + font-weight: 400; + margin-left: 8px; + margin-right: 8px; + + &:hover { + color: #E2E2E2; + } + } + } + } + } + + > #githubButtons { + margin-right: 30px; + @media only screen and (max-width: 1059px) { + display: none; + } + + > .github-badge { + margin-left: 8px; + } + } +} + + +// cexpanded on mobile devices after pressing the hamburger button +nav.nav-collapsed { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + flex-wrap: wrap; + background-color: #343A40; + padding-top: 8px; + padding-left: 16px; + padding-bottom: 8px; + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 10; + + > .navbar-hamburger { + display: none; + background-color: #343A40; + border-color: rgba(255, 255, 255, .1); + + @media screen and (max-width: 990px) { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + cursor: pointer; + padding-top: 4px; + padding-bottom: 4px; + padding-left: 12px; + padding-right: 12px; + } + } + + > .navbar-wrapper { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + margin-top: 8px; + width: 100%; + + > .navbar-brand { + font-size: 16px; + color: #ffffff; + font-weight: 400; + margin-left: 8px; + margin-right: 8px; + margin-top: 8px; + margin-bottom: 8px; + cursor: pointer; + width: 100%; + + > img { + border-radius: 3px + } + + &:hover { + color: #bdbdbd; + } + } + + > .navbar-nav { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + width: 100%; + list-style: none; + + > .nav-item { + cursor: pointer; + color: #e2e2e2; + width: 100%; + margin-top: 8px; + margin-bottom: 8px; + + > a.nav-link { + color: #b9b9b9; + font-size: 14px; + font-weight: 400; + margin-left: 8px; + margin-right: 8px; + + &:hover { + color: #E2E2E2; + } + } + } + } + } +} + + + diff --git a/examples/universal/src/app/plain-gallery/plain-gallery.component.ts b/examples/universal/src/app/plain-gallery/plain-gallery.component.ts new file mode 100644 index 00000000..5b517f01 --- /dev/null +++ b/examples/universal/src/app/plain-gallery/plain-gallery.component.ts @@ -0,0 +1,297 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2021 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; + +import { + GridLayout, + Image, + LineLayout, + PlainGalleryConfig, + PlainGalleryStrategy, + ModalGalleryService, + ModalGalleryRef, + PlainLibConfig +} from '@ks89/angular-modal-gallery'; + +@Component({ + selector: 'ks-plain-gallery-page', + templateUrl: './plain-gallery.html', + styleUrls: ['./plain-gallery.scss'], + standalone: false +}) +export class PlainGalleryExampleComponent { + plainGalleryRow: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout({ width: '80px', height: '80px' }, { length: 2, wrap: true }, 'flex-start') + }; + plainGalleryRowSpaceAround: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout({ width: '50px', height: '50px' }, { length: 2, wrap: true }, 'space-around') + }; + plainGalleryRowATags: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout({ width: '95px', height: '63px' }, { length: 4, wrap: true }, 'flex-start'), + // when advanced is defined, additionalBackground: '50% 50%/cover' will be used by default. + // I added this here, to be more explicit. + advanced: { aTags: true, additionalBackground: '50% 50%/cover' } + }; + + plainGalleryColumn: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.COLUMN, + layout: new LineLayout({ width: '50px', height: '50px' }, { length: 3, wrap: true }, 'flex-start') + }; + + plainGalleryGrid: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.GRID, + layout: new GridLayout({ width: '80px', height: '80px' }, { length: 3, wrap: true }) + }; + + images: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: '../assets/images/gallery/img2.jpg', + description: 'Description 2' + }), + new Image( + 2, + { + img: '../assets/images/gallery/img3.jpg', + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new Image(3, { + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new Image(4, { img: '../assets/images/gallery/img5.jpg' }, { img: '../assets/images/gallery/thumbs/img5.jpg' }) + ]; + + emptyImagesArray: Image[] = []; + + fallbackImages: Image[] = [ + new Image(0, { + // this file is not available so the browser returns an error + img: '../assets/images/gallery/UNEXISTING_IMG1.jpg', + // because the img above doesn't exists, the library will use this file + fallbackImg: '../assets/images/gallery/fallback1.jpg' + }), + new Image(1, { + img: '../assets/images/gallery/UNEXISTING_IMG2.jpg', + fallbackImg: '../assets/images/gallery/fallback2.jpg' + }), + new Image( + 2, + { + img: '../assets/images/gallery/UNEXISTING_IMG3.jpg', + fallbackImg: '../assets/images/gallery/fallback3.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG3.png', + fallbackImg: '../assets/images/gallery/fallback3.jpg' + } + ), + new Image(3, { + img: '../assets/images/gallery/UNEXISTING_IMG4.jpg', + fallbackImg: '../assets/images/gallery/fallback4.jpg' + }), + new Image( + 4, + { + img: '../assets/images/gallery/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback5.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback5.jpg' + } + ) + ]; + + imagesRect: Image[] = [ + new Image( + 0, + { + img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1' + }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg' } + ), + new Image(1, { img: '../assets/images/gallery/pexels-photo-47223.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg' }), + new Image( + 2, + { + img: '../assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3' + }, + { + img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '../assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4' + }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg' } + ), + new Image(4, { img: '../assets/images/gallery/pexels-photo-93750.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg' }), + new Image( + 5, + { + img: '../assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6' + }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg' } + ), + new Image(6, { img: '../assets/images/gallery/pexels-photo-96947.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg' }) + ]; + + imagesRectNoTitles: Image[] = [ + new Image( + 0, + { img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', title: '' } + ), + new Image( + 1, + { img: '../assets/images/gallery/pexels-photo-47223.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg', title: '' } + ), + new Image( + 2, + { img: '../assets/images/gallery/pexels-photo-52062.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', title: '' } + ), + new Image( + 3, + { img: '../assets/images/gallery/pexels-photo-66943.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', title: '' } + ), + new Image( + 4, + { img: '../assets/images/gallery/pexels-photo-93750.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg', title: '' } + ), + new Image( + 5, + { img: '../assets/images/gallery/pexels-photo-94420.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg', title: '' } + ), + new Image( + 6, + { img: '../assets/images/gallery/pexels-photo-96947.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg', title: '' } + ) + ]; + + libConfigPlainGalleryRow: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryRow + }; + libConfigPlainGalleryRowSpaceAround: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryRowSpaceAround + }; + libConfigPlainGalleryRowATags: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryRowATags + }; + libConfigPlainGalleryColumn: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryColumn + }; + libConfigPlainGalleryGrid: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryGrid + }; + + constructor(private modalGalleryService: ModalGalleryService, private sanitizer: DomSanitizer) {} + + openImageModalRow(id: number, image: Image): void { + console.log('Opening modal gallery from custom plain gallery row, with image: ', image); + const index: number = this.getCurrentIndexCustomLayout(image, this.images); + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: this.images, + currentImage: this.images[index] + }) as ModalGalleryRef; + } + + openImageModalColumn(id: number, image: Image): void { + console.log('Opening modal gallery from custom plain gallery column, with image: ', image); + const index: number = this.getCurrentIndexCustomLayout(image, this.images); + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: this.images, + currentImage: this.images[index] + }) as ModalGalleryRef; + } + + openImageModalRowDescription(id: number, image: Image): void { + console.log('Opening modal gallery from custom plain gallery row and description, with image: ', image); + const index: number = this.getCurrentIndexCustomLayout(image, this.imagesRect); + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: this.imagesRect, + currentImage: this.imagesRect[index] + }) as ModalGalleryRef; + } + + addRandomImage(): void { + // add to images array + const imageToCopy: Image = this.images[Math.floor(Math.random() * this.images.length)]; + const newImage: Image = new Image(this.images.length - 1 + 1, imageToCopy.modal, imageToCopy.plain); + this.images = [...this.images, newImage]; + // add also to imagesRect + const imageRectToCopy: Image = this.imagesRect[Math.floor(Math.random() * this.imagesRect.length)]; + const newImageRect: Image = new Image(this.imagesRect.length - 1 + 1, imageRectToCopy.modal, imageRectToCopy.plain); + this.imagesRect = [...this.imagesRect, newImageRect]; + } + + onShow(id: number, index: number, images: Image[] = this.images): void { + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images, + currentImage: images[index] + }) as ModalGalleryRef; + } + + trackById(index: number, item: Image): number { + return item.id; + } + + private getCurrentIndexCustomLayout(image: Image, images: Image[]): number { + return image ? images.indexOf(image) : -1; + } +} diff --git a/examples/universal/src/app/plain-gallery/plain-gallery.html b/examples/universal/src/app/plain-gallery/plain-gallery.html new file mode 100644 index 00000000..73f06879 --- /dev/null +++ b/examples/universal/src/app/plain-gallery/plain-gallery.html @@ -0,0 +1,152 @@ +

Plain Gallery

+
+ +

If you want, you can add a random image to every example + +

+
+
+

Layout examples

+
+

P1 - (id=200) - row plain gallery layout (limit 2) and custom size

+
+ +
+
+
+

P2 - (id=201) - row plain gallery layout space around (limit 2)

+
+ +
+
+
+

P3 - (id=202) - row plain gallery layout with a tags and custom rectangular sizes (limit 4)

+
+ +
+
+
+

P4 - (id=203) - column plain gallery layout (limit 3)

+
+ +
+
+
+

P5 - (id=204) - grid plain gallery layout and custom size

+
+ +
+
+
+

P6 - (id=205) - full custom plain gallery (row) with image pointer

+
+
+ + + +
+
+
+
+

P7 - (id=206) - full custom plain gallery (column) with image pointer

+
+
+ + + +
+
+
+
+

P8 - (id=207) - full custom plain gallery (row) with descriptions

+
+
+ +
+ +
{{img.modal.description ? img.modal.description : 'No description available'}} +
+
+
+
+
+
+
+

P9 - (id=208) - row plain gallery layout with fallback images when it's not possible to load normal images (to fix issue #194)

+
+ +
+
+
+

P10 - (id=209) - row plain gallery layout with a tags and custom rectangular sizes (limit 4) + fallback images when it's not possible to load normal images (to fix issue #194)

+
+ +
+
+
+

P11 - (id=210) - row plain gallery layout (limit 2) and custom size + remove title attribute on images

+
+ +
+
+
+

P12 - (id=211) - row plain gallery layout with an empty images array

+
+ +
+
+
diff --git a/examples/universal/src/app/plain-gallery/plain-gallery.scss b/examples/universal/src/app/plain-gallery/plain-gallery.scss new file mode 100644 index 00000000..7310ae64 --- /dev/null +++ b/examples/universal/src/app/plain-gallery/plain-gallery.scss @@ -0,0 +1,169 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2021 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +:host { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + margin-left: 20px; + margin-right: 20px; +} + +section { + width: 100%; +} + +$text-color: #fff; +$background: rgba(0, 0, 0, .7); + +button { + background-color: #0060b7; + color: white; + height: 25px; + width: auto; + border: 0; + border-radius: 5px; + cursor: pointer; + + &:hover { + background-color: #0086ff; + } +} + +.my-app-custom-plain-container-row { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + .my-app-custom-image-row { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-column { + align-items: center; + display: flex; + flex-direction: column; + justify-content: flex-start; + + .my-app-custom-image-column { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-with-desc { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + figure { + margin: 0; + position: relative; + + img { + max-width: 100%; + height: auto; + cursor: pointer; + } + + figcaption { + background: rgba(0, 0, 0, .5); + color: #fff; + font-size: 85%; + padding: 5px; + position: absolute; + bottom: 3px; + left: 0; + right: 0; + } + } + + .description { + font-weight: bold; + text-align: center; + } + + .my-app-custom-image-with-desc { + height: auto; + margin-right: 2px; + width: 200px; + align-self: start; + } +} + +.more { + background: $background; + cursor: pointer; + color: $text-color; + padding-top: 4px; + height: 46px; + position: absolute; + text-align: center; + width: 50px; +} + + +.transcluded { + color: white; + font-weight: 600; + font-size: 24px; + text-align: center; + position: absolute; + top: 50%; + width: 100%; + pointer-events: none; +} + +.title { + margin-top: 40px; +} diff --git a/examples/universal/src/assets/images/gallery/fallback-carousel1.jpg b/examples/universal/src/assets/images/gallery/fallback-carousel1.jpg new file mode 100644 index 00000000..5d49263f Binary files /dev/null and b/examples/universal/src/assets/images/gallery/fallback-carousel1.jpg differ diff --git a/examples/universal/src/assets/images/gallery/fallback-carousel2.jpg b/examples/universal/src/assets/images/gallery/fallback-carousel2.jpg new file mode 100644 index 00000000..2c2ce26a Binary files /dev/null and b/examples/universal/src/assets/images/gallery/fallback-carousel2.jpg differ diff --git a/examples/universal/src/assets/images/gallery/fallback-carousel3.jpg b/examples/universal/src/assets/images/gallery/fallback-carousel3.jpg new file mode 100644 index 00000000..a4ea6b40 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/fallback-carousel3.jpg differ diff --git a/examples/universal/src/assets/images/gallery/fallback-carousel4.jpg b/examples/universal/src/assets/images/gallery/fallback-carousel4.jpg new file mode 100644 index 00000000..0d59507d Binary files /dev/null and b/examples/universal/src/assets/images/gallery/fallback-carousel4.jpg differ diff --git a/examples/universal/src/assets/images/gallery/fallback-carousel5.jpg b/examples/universal/src/assets/images/gallery/fallback-carousel5.jpg new file mode 100644 index 00000000..5511feb8 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/fallback-carousel5.jpg differ diff --git a/examples/universal/src/assets/images/gallery/fallback1.jpg b/examples/universal/src/assets/images/gallery/fallback1.jpg new file mode 100644 index 00000000..0827c782 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/fallback1.jpg differ diff --git a/examples/universal/src/assets/images/gallery/fallback2.jpg b/examples/universal/src/assets/images/gallery/fallback2.jpg new file mode 100644 index 00000000..6562c517 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/fallback2.jpg differ diff --git a/examples/universal/src/assets/images/gallery/fallback3.jpg b/examples/universal/src/assets/images/gallery/fallback3.jpg new file mode 100644 index 00000000..3a3d63f4 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/fallback3.jpg differ diff --git a/examples/universal/src/assets/images/gallery/fallback4.jpg b/examples/universal/src/assets/images/gallery/fallback4.jpg new file mode 100644 index 00000000..0dfe8551 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/fallback4.jpg differ diff --git a/examples/universal/src/assets/images/gallery/fallback5.jpg b/examples/universal/src/assets/images/gallery/fallback5.jpg new file mode 100644 index 00000000..38da58e4 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/fallback5.jpg differ diff --git a/examples/universal/src/assets/images/gallery/img1.jpg b/examples/universal/src/assets/images/gallery/img1.jpg new file mode 100644 index 00000000..7d358899 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/img1.jpg differ diff --git a/examples/universal/src/assets/images/gallery/img2.jpg b/examples/universal/src/assets/images/gallery/img2.jpg new file mode 100644 index 00000000..4c101c12 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/img2.jpg differ diff --git a/examples/universal/src/assets/images/gallery/img2.png b/examples/universal/src/assets/images/gallery/img2.png new file mode 100644 index 00000000..295cb1f4 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/img2.png differ diff --git a/examples/universal/src/assets/images/gallery/img3.jpg b/examples/universal/src/assets/images/gallery/img3.jpg new file mode 100644 index 00000000..c6b1c22d Binary files /dev/null and b/examples/universal/src/assets/images/gallery/img3.jpg differ diff --git a/examples/universal/src/assets/images/gallery/img4.jpg b/examples/universal/src/assets/images/gallery/img4.jpg new file mode 100644 index 00000000..403482ae Binary files /dev/null and b/examples/universal/src/assets/images/gallery/img4.jpg differ diff --git a/examples/universal/src/assets/images/gallery/img5.jpg b/examples/universal/src/assets/images/gallery/img5.jpg new file mode 100644 index 00000000..bf97ab6c Binary files /dev/null and b/examples/universal/src/assets/images/gallery/img5.jpg differ diff --git a/examples/universal/src/assets/images/gallery/milan-pegasus-gallery-statue-1024w.jpg b/examples/universal/src/assets/images/gallery/milan-pegasus-gallery-statue-1024w.jpg new file mode 100644 index 00000000..c0a922d1 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/milan-pegasus-gallery-statue-1024w.jpg differ diff --git a/examples/universal/src/assets/images/gallery/milan-pegasus-gallery-statue-480w.jpg b/examples/universal/src/assets/images/gallery/milan-pegasus-gallery-statue-480w.jpg new file mode 100644 index 00000000..ac54d7d7 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/milan-pegasus-gallery-statue-480w.jpg differ diff --git a/examples/universal/src/assets/images/gallery/milan-pegasus-gallery-statue-768w.jpg b/examples/universal/src/assets/images/gallery/milan-pegasus-gallery-statue-768w.jpg new file mode 100644 index 00000000..dba50163 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/milan-pegasus-gallery-statue-768w.jpg differ diff --git a/examples/universal/src/assets/images/gallery/milan-pegasus-gallery-statue.jpg b/examples/universal/src/assets/images/gallery/milan-pegasus-gallery-statue.jpg new file mode 100644 index 00000000..f2c02760 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/milan-pegasus-gallery-statue.jpg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-135230-1024w.png b/examples/universal/src/assets/images/gallery/pexels-photo-135230-1024w.png new file mode 100644 index 00000000..a543d4db Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-135230-1024w.png differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-135230-480w.png b/examples/universal/src/assets/images/gallery/pexels-photo-135230-480w.png new file mode 100644 index 00000000..dc29041e Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-135230-480w.png differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-135230-768w.png b/examples/universal/src/assets/images/gallery/pexels-photo-135230-768w.png new file mode 100644 index 00000000..b04917ed Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-135230-768w.png differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-135230.png b/examples/universal/src/assets/images/gallery/pexels-photo-135230.png new file mode 100644 index 00000000..8aa887fd Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-135230.png differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-47223-1024w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-47223-1024w.jpeg new file mode 100644 index 00000000..f7931c21 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-47223-1024w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-47223-480w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-47223-480w.jpeg new file mode 100644 index 00000000..14897ecf Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-47223-480w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-47223-768w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-47223-768w.jpeg new file mode 100644 index 00000000..73f72c9a Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-47223-768w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-47223.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-47223.jpeg new file mode 100644 index 00000000..46ea1f75 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-47223.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-52062-1024w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-52062-1024w.jpeg new file mode 100644 index 00000000..a7052fd3 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-52062-1024w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-52062-480w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-52062-480w.jpeg new file mode 100644 index 00000000..1ac7ce8c Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-52062-480w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-52062-768w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-52062-768w.jpeg new file mode 100644 index 00000000..e1f3256c Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-52062-768w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-52062.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-52062.jpeg new file mode 100644 index 00000000..0c9502e4 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-52062.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-547115-1024w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-547115-1024w.jpeg new file mode 100644 index 00000000..592a1516 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-547115-1024w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-547115-480w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-547115-480w.jpeg new file mode 100644 index 00000000..15c404dd Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-547115-480w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-547115-768w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-547115-768w.jpeg new file mode 100644 index 00000000..68fa15da Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-547115-768w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-547115.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-547115.jpeg new file mode 100644 index 00000000..4056b197 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-547115.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-556664-1024w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-556664-1024w.jpeg new file mode 100644 index 00000000..b56cf006 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-556664-1024w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-556664-480w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-556664-480w.jpeg new file mode 100644 index 00000000..f7990e34 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-556664-480w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-556664-768w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-556664-768w.jpeg new file mode 100644 index 00000000..cbb74582 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-556664-768w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-556664.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-556664.jpeg new file mode 100644 index 00000000..33383d36 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-556664.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-66943-1024w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-66943-1024w.jpeg new file mode 100644 index 00000000..18988bf3 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-66943-1024w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-66943-480w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-66943-480w.jpeg new file mode 100644 index 00000000..c40829b9 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-66943-480w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-66943-768w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-66943-768w.jpeg new file mode 100644 index 00000000..953ef6f3 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-66943-768w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-66943.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-66943.jpeg new file mode 100644 index 00000000..8dd20157 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-66943.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-787594-1024w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-787594-1024w.jpeg new file mode 100644 index 00000000..52113fef Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-787594-1024w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-787594-480w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-787594-480w.jpeg new file mode 100644 index 00000000..3b97fb45 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-787594-480w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-787594-768w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-787594-768w.jpeg new file mode 100644 index 00000000..b08cc133 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-787594-768w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-787594.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-787594.jpeg new file mode 100644 index 00000000..e2986131 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-787594.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-803105-1024w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-803105-1024w.jpeg new file mode 100644 index 00000000..99bb60cd Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-803105-1024w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-803105-480w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-803105-480w.jpeg new file mode 100644 index 00000000..815624dc Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-803105-480w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-803105-768w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-803105-768w.jpeg new file mode 100644 index 00000000..1118cde8 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-803105-768w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-803105.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-803105.jpeg new file mode 100644 index 00000000..8b7c44a4 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-803105.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-93750-1024w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-93750-1024w.jpeg new file mode 100644 index 00000000..bf1e8eaf Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-93750-1024w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-93750-480w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-93750-480w.jpeg new file mode 100644 index 00000000..08020dbe Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-93750-480w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-93750-768w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-93750-768w.jpeg new file mode 100644 index 00000000..8fe37d40 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-93750-768w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-93750.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-93750.jpeg new file mode 100644 index 00000000..ab537b02 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-93750.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-94420-1024w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-94420-1024w.jpeg new file mode 100644 index 00000000..c8a13148 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-94420-1024w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-94420-480w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-94420-480w.jpeg new file mode 100644 index 00000000..acc790e7 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-94420-480w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-94420-768w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-94420-768w.jpeg new file mode 100644 index 00000000..11fbaad9 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-94420-768w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-94420.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-94420.jpeg new file mode 100644 index 00000000..d3ebb012 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-94420.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-96947-1024w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-96947-1024w.jpeg new file mode 100644 index 00000000..3e4a701f Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-96947-1024w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-96947-480w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-96947-480w.jpeg new file mode 100644 index 00000000..0248070f Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-96947-480w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-96947-768w.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-96947-768w.jpeg new file mode 100644 index 00000000..c74f523e Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-96947-768w.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/pexels-photo-96947.jpeg b/examples/universal/src/assets/images/gallery/pexels-photo-96947.jpeg new file mode 100644 index 00000000..c6965748 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/pexels-photo-96947.jpeg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/fallback-carousel1.jpg b/examples/universal/src/assets/images/gallery/thumbs/fallback-carousel1.jpg new file mode 100644 index 00000000..5ce2a4ed Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/fallback-carousel1.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/fallback-carousel2.jpg b/examples/universal/src/assets/images/gallery/thumbs/fallback-carousel2.jpg new file mode 100644 index 00000000..6417a30b Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/fallback-carousel2.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/fallback-carousel3.jpg b/examples/universal/src/assets/images/gallery/thumbs/fallback-carousel3.jpg new file mode 100644 index 00000000..a0939a7a Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/fallback-carousel3.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/fallback-carousel4.jpg b/examples/universal/src/assets/images/gallery/thumbs/fallback-carousel4.jpg new file mode 100644 index 00000000..5be118b7 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/fallback-carousel4.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/fallback-carousel5.jpg b/examples/universal/src/assets/images/gallery/thumbs/fallback-carousel5.jpg new file mode 100644 index 00000000..c61eb0ee Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/fallback-carousel5.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/fallback1.jpg b/examples/universal/src/assets/images/gallery/thumbs/fallback1.jpg new file mode 100644 index 00000000..2afb5530 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/fallback1.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/fallback2.jpg b/examples/universal/src/assets/images/gallery/thumbs/fallback2.jpg new file mode 100644 index 00000000..140e9718 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/fallback2.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/fallback3.jpg b/examples/universal/src/assets/images/gallery/thumbs/fallback3.jpg new file mode 100644 index 00000000..11115387 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/fallback3.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/fallback4.jpg b/examples/universal/src/assets/images/gallery/thumbs/fallback4.jpg new file mode 100644 index 00000000..9737793b Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/fallback4.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/fallback5.jpg b/examples/universal/src/assets/images/gallery/thumbs/fallback5.jpg new file mode 100644 index 00000000..88915773 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/fallback5.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/img1.jpg b/examples/universal/src/assets/images/gallery/thumbs/img1.jpg new file mode 100644 index 00000000..68e10d14 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/img1.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/img2.jpg b/examples/universal/src/assets/images/gallery/thumbs/img2.jpg new file mode 100644 index 00000000..3b69746a Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/img2.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/img3.png b/examples/universal/src/assets/images/gallery/thumbs/img3.png new file mode 100644 index 00000000..3f0bf060 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/img3.png differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/img4.jpg b/examples/universal/src/assets/images/gallery/thumbs/img4.jpg new file mode 100644 index 00000000..d08ebe7f Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/img4.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/img5.jpg b/examples/universal/src/assets/images/gallery/thumbs/img5.jpg new file mode 100644 index 00000000..b932ee9f Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/img5.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg b/examples/universal/src/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg new file mode 100644 index 00000000..6881e08c Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg b/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg new file mode 100644 index 00000000..be93d546 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg b/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg new file mode 100644 index 00000000..eb99fe42 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg b/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg new file mode 100644 index 00000000..e33dc4be Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg b/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg new file mode 100644 index 00000000..feae47af Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg b/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg new file mode 100644 index 00000000..075cdd51 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg differ diff --git a/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg b/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg new file mode 100644 index 00000000..ab777557 Binary files /dev/null and b/examples/universal/src/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg differ diff --git a/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-106006-thumb.jpg b/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-106006-thumb.jpg new file mode 100644 index 00000000..e80e1a53 Binary files /dev/null and b/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-106006-thumb.jpg differ diff --git a/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-106006.jpg b/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-106006.jpg new file mode 100644 index 00000000..6baa8325 Binary files /dev/null and b/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-106006.jpg differ diff --git a/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-464336-thumb.jpg b/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-464336-thumb.jpg new file mode 100644 index 00000000..7bd64447 Binary files /dev/null and b/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-464336-thumb.jpg differ diff --git a/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-464336.jpg b/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-464336.jpg new file mode 100644 index 00000000..c7253d57 Binary files /dev/null and b/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-464336.jpg differ diff --git a/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-74506-thumb.jpg b/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-74506-thumb.jpg new file mode 100644 index 00000000..24028aa0 Binary files /dev/null and b/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-74506-thumb.jpg differ diff --git a/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-74506.jpg b/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-74506.jpg new file mode 100644 index 00000000..c4973505 Binary files /dev/null and b/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-74506.jpg differ diff --git a/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-thumb.jpg b/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-thumb.jpg new file mode 100644 index 00000000..34615206 Binary files /dev/null and b/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo-thumb.jpg differ diff --git a/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo.jpg b/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo.jpg new file mode 100644 index 00000000..3ceffcbe Binary files /dev/null and b/examples/universal/src/assets/images/loading-spinner-samples/pexels-photo.jpg differ diff --git a/examples/universal/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891-thumb.jpg b/examples/universal/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891-thumb.jpg new file mode 100644 index 00000000..8cfda5fa Binary files /dev/null and b/examples/universal/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891-thumb.jpg differ diff --git a/examples/universal/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891.jpg b/examples/universal/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891.jpg new file mode 100644 index 00000000..9457c1c6 Binary files /dev/null and b/examples/universal/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891.jpg differ diff --git a/examples/universal/src/assets/menu.svg b/examples/universal/src/assets/menu.svg new file mode 100644 index 00000000..65fc9003 --- /dev/null +++ b/examples/universal/src/assets/menu.svg @@ -0,0 +1,3 @@ + + + diff --git a/examples/universal/src/favicon.png b/examples/universal/src/favicon.png new file mode 100644 index 00000000..4e279875 Binary files /dev/null and b/examples/universal/src/favicon.png differ diff --git a/examples/universal/src/index.html b/examples/universal/src/index.html new file mode 100644 index 00000000..dc3730df --- /dev/null +++ b/examples/universal/src/index.html @@ -0,0 +1,18 @@ + + + + + @ks89/angular-modal-gallery demo + + + + + + + + + + + diff --git a/examples/universal/src/main.server.ts b/examples/universal/src/main.server.ts new file mode 100644 index 00000000..dfb6fdb3 --- /dev/null +++ b/examples/universal/src/main.server.ts @@ -0,0 +1 @@ +export { AppServerModule as default } from './app/app.module.server'; diff --git a/examples/universal/src/main.ts b/examples/universal/src/main.ts new file mode 100644 index 00000000..1d335a67 --- /dev/null +++ b/examples/universal/src/main.ts @@ -0,0 +1,8 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule, { + ngZoneEventCoalescing: true +}) + .catch(err => console.error(err)); diff --git a/examples/universal/src/server.ts b/examples/universal/src/server.ts new file mode 100644 index 00000000..4b2dc52c --- /dev/null +++ b/examples/universal/src/server.ts @@ -0,0 +1,65 @@ +import { APP_BASE_HREF } from '@angular/common'; +import { CommonEngine, isMainModule } from '@angular/ssr/node'; +import express from 'express'; +import { dirname, join, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import AppServerModule from './main.server'; + +const serverDistFolder = dirname(fileURLToPath(import.meta.url)); +const browserDistFolder = resolve(serverDistFolder, '../browser'); +const indexHtml = join(serverDistFolder, 'index.server.html'); + +const app = express(); +const commonEngine = new CommonEngine(); + +/** + * Example Express Rest API endpoints can be defined here. + * Uncomment and define endpoints as necessary. + * + * Example: + * ```ts + * app.get('/api/**', (req, res) => { + * // Handle API request + * }); + * ``` + */ + +/** + * Serve static files from /browser + */ +app.get( + '**', + express.static(browserDistFolder, { + maxAge: '1y', + index: 'index.html' + }), +); + +/** + * Handle all other requests by rendering the Angular application. + */ +app.get('**', (req, res, next) => { + const { protocol, originalUrl, baseUrl, headers } = req; + + commonEngine + .render({ + bootstrap: AppServerModule, + documentFilePath: indexHtml, + url: `${protocol}://${headers.host}${originalUrl}`, + publicPath: browserDistFolder, + providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }], + }) + .then((html) => res.send(html)) + .catch((err) => next(err)); +}); + +/** + * Start the server if this module is the main entry point. + * The server listens on the port defined by the `PORT` environment variable, or defaults to 4000. + */ +if (isMainModule(import.meta.url)) { + const port = process.env['PORT'] || 4000; + app.listen(port, () => { + console.log(`Node Express server listening on http://localhost:${port}`); + }); +} diff --git a/examples/universal/src/styles.scss b/examples/universal/src/styles.scss new file mode 100644 index 00000000..47d84e5a --- /dev/null +++ b/examples/universal/src/styles.scss @@ -0,0 +1,61 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// You can add global styles to this file, and also import other style files + +// ***************************************************************** +// *********** required by @ks89/angular-modal-gallery ************* +// ***************************************************************** +// ATTENTION: You have to install @angular/cdk to be able to use @ks89/angular-modal-gallery properly +@import "@angular/cdk/overlay-prebuilt.css"; + +.ks-modal-gallery-backdrop { + background: #000 !important;; + opacity: 0.85 !important;; +} + +.ks-modal-gallery-panel { + z-index: 90000 !important; +} +// ***************************************************************** +// ***************************************************************** +// ***************************************************************** + +body { + font-family: "Montserrat", sans-serif; + margin: 0; + padding: 0; +} + +// Not required by angular-modal-gallery. Used only in this demo +.red-text { + color: red; +} + +.title { + text-align: center; + color: red; +} + +.center-text { + text-align: center; +} diff --git a/examples/universal/tsconfig.app.json b/examples/universal/tsconfig.app.json new file mode 100644 index 00000000..9ab8527b --- /dev/null +++ b/examples/universal/tsconfig.app.json @@ -0,0 +1,19 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [ + "node" + ] + }, + "files": [ + "src/main.ts", + "src/main.server.ts", + "src/server.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/examples/universal/tsconfig.json b/examples/universal/tsconfig.json new file mode 100644 index 00000000..3110e6e1 --- /dev/null +++ b/examples/universal/tsconfig.json @@ -0,0 +1,32 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "compileOnSave": false, + "compilerOptions": { + "outDir": "./dist/out-tsc", + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "isolatedModules": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "moduleResolution": "bundler", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "useDefineForClassFields": false, // to inject sanitizer without errors + "lib": [ + "ES2022", + "dom" + ] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/examples/universal/tsconfig.spec.json b/examples/universal/tsconfig.spec.json new file mode 100644 index 00000000..5fb748d9 --- /dev/null +++ b/examples/universal/tsconfig.spec.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/index.html b/index.html deleted file mode 100644 index f3834c0e..00000000 --- a/index.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - Angular 2 QuickStart - - - - - - - - - - - - - - - - - - - - - - - - Loading... - - - diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..9b31e47e --- /dev/null +++ b/package-lock.json @@ -0,0 +1,16264 @@ +{ + "name": "angular-modal-gallery", + "version": "13.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "angular-modal-gallery", + "version": "13.0.0", + "license": "MIT", + "dependencies": { + "@angular/cdk": "^19.0.4", + "@angular/common": "^19.0.5", + "@angular/compiler": "^19.0.5", + "@angular/core": "^19.0.5", + "@angular/forms": "^19.0.5", + "@angular/platform-browser": "^19.0.5", + "@angular/platform-browser-dynamic": "^19.0.5", + "@angular/router": "^19.0.5", + "@fortawesome/fontawesome-svg-core": "^6.7.2", + "@fortawesome/free-solid-svg-icons": "^6.7.2", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^19.0.6", + "@angular/cli": "~19.0.6", + "@angular/compiler-cli": "^19.0.5", + "@types/jasmine": "~5.1.0", + "@types/node": "^20.12.13", + "coveralls": "^3.1.1", + "cpr": "^3.0.1", + "cross-env": "^7.0.0", + "husky": "^9.1.7", + "jasmine-core": "~5.4.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "karma-mocha-reporter": "^2.2.5", + "license-checker": "^25.0.1", + "madge": "^8.0.0", + "ng-packagr": "^19.0.1", + "prettier": "^3.4.2", + "pretty-quick": "^4.0.0", + "rimraf": "^6.0.1", + "snyk": "^1.1294.3", + "typescript": "~5.6.3" + }, + "engines": { + "node": ">=20.14.0", + "npm": ">=10.2.4" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@angular-devkit/architect": { + "version": "0.1900.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1900.6.tgz", + "integrity": "sha512-w11bAXQnNWBawTJfQPjvaTRrzrqsOUm9tK9WNvaia/xjiRFpmO0CfmKtn3axNSEJM8jb/czaNQrgTwG+TGc/8g==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "19.0.6", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/architect/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/architect/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/architect/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/architect/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/build-angular": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-19.0.6.tgz", + "integrity": "sha512-dWTAsE6BSI8z0xglQdYBdqTBwg1Q+RWE3OrmlGs+520Dcoq/F0Z41Y1F3MiuHuQPdDAIQr88iB0APkIRW4clMg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1900.6", + "@angular-devkit/build-webpack": "0.1900.6", + "@angular-devkit/core": "19.0.6", + "@angular/build": "19.0.6", + "@babel/core": "7.26.0", + "@babel/generator": "7.26.2", + "@babel/helper-annotate-as-pure": "7.25.9", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-transform-async-generator-functions": "7.25.9", + "@babel/plugin-transform-async-to-generator": "7.25.9", + "@babel/plugin-transform-runtime": "7.25.9", + "@babel/preset-env": "7.26.0", + "@babel/runtime": "7.26.0", + "@discoveryjs/json-ext": "0.6.3", + "@ngtools/webpack": "19.0.6", + "@vitejs/plugin-basic-ssl": "1.1.0", + "ansi-colors": "4.1.3", + "autoprefixer": "10.4.20", + "babel-loader": "9.2.1", + "browserslist": "^4.21.5", + "copy-webpack-plugin": "12.0.2", + "css-loader": "7.1.2", + "esbuild-wasm": "0.24.0", + "fast-glob": "3.3.2", + "http-proxy-middleware": "3.0.3", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", + "karma-source-map-support": "1.4.0", + "less": "4.2.0", + "less-loader": "12.2.0", + "license-webpack-plugin": "4.0.2", + "loader-utils": "3.3.1", + "mini-css-extract-plugin": "2.9.2", + "open": "10.1.0", + "ora": "5.4.1", + "picomatch": "4.0.2", + "piscina": "4.7.0", + "postcss": "8.4.49", + "postcss-loader": "8.1.1", + "resolve-url-loader": "5.0.0", + "rxjs": "7.8.1", + "sass": "1.80.7", + "sass-loader": "16.0.3", + "semver": "7.6.3", + "source-map-loader": "5.0.0", + "source-map-support": "0.5.21", + "terser": "5.36.0", + "tree-kill": "1.2.2", + "tslib": "2.8.1", + "webpack": "5.96.1", + "webpack-dev-middleware": "7.4.2", + "webpack-dev-server": "5.1.0", + "webpack-merge": "6.0.1", + "webpack-subresource-integrity": "5.1.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "esbuild": "0.24.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^19.0.0", + "@angular/localize": "^19.0.0", + "@angular/platform-server": "^19.0.0", + "@angular/service-worker": "^19.0.0", + "@angular/ssr": "^19.0.6", + "@web/test-runner": "^0.19.0", + "browser-sync": "^3.0.2", + "jest": "^29.5.0", + "jest-environment-jsdom": "^29.5.0", + "karma": "^6.3.0", + "ng-packagr": "^19.0.0", + "protractor": "^7.0.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=5.5 <5.7" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "@web/test-runner": { + "optional": true + }, + "browser-sync": { + "optional": true + }, + "jest": { + "optional": true + }, + "jest-environment-jsdom": { + "optional": true + }, + "karma": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "protractor": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.1900.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1900.6.tgz", + "integrity": "sha512-WehtVrbBow4fc7hsaUKb+BZ6MDE5lO98/tgv7GR5PkRdGKnyLA0pW1AfPLJJQDgcaKjneramMhDFNc1eGSX0mQ==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1900.6", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "webpack": "^5.30.0", + "webpack-dev-server": "^5.0.2" + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.0.6.tgz", + "integrity": "sha512-R9hlHfAh1HKoIWgnYJlOEKhUezhTNl0fpUmHxG2252JSY5FLRxmYArTtJYYmbNdBbsBLNg3UHyM/GBPvJSA3NQ==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "19.0.6", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.12", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/build": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-19.0.6.tgz", + "integrity": "sha512-KEVNLgTZUF2dfpOYQn+yR2HONHUTxq/2rFVhiK9qAvrm/m+uKJNEXx7hGtbRyoqenZff4ScJq+7feITUldfX8g==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1900.6", + "@babel/core": "7.26.0", + "@babel/helper-annotate-as-pure": "7.25.9", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-syntax-import-attributes": "7.26.0", + "@inquirer/confirm": "5.0.2", + "@vitejs/plugin-basic-ssl": "1.1.0", + "beasties": "0.1.0", + "browserslist": "^4.23.0", + "esbuild": "0.24.0", + "fast-glob": "3.3.2", + "https-proxy-agent": "7.0.5", + "istanbul-lib-instrument": "6.0.3", + "listr2": "8.2.5", + "magic-string": "0.30.12", + "mrmime": "2.0.0", + "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "4.0.2", + "piscina": "4.7.0", + "rollup": "4.26.0", + "sass": "1.80.7", + "semver": "7.6.3", + "vite": "5.4.11", + "watchpack": "2.4.2" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "lmdb": "3.1.5" + }, + "peerDependencies": { + "@angular/compiler": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "@angular/localize": "^19.0.0", + "@angular/platform-server": "^19.0.0", + "@angular/service-worker": "^19.0.0", + "@angular/ssr": "^19.0.6", + "less": "^4.2.0", + "postcss": "^8.4.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=5.5 <5.7" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "less": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular/build/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular/cdk": { + "version": "19.0.4", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-19.0.4.tgz", + "integrity": "sha512-P8V1n6AFFjBUJG3YRgw8DiiNDWPZVrwQ42wbwgZxd4s2TQAuNFg3YY8h/DSMVxt2sXpavrshZsoLtP9yLKZjHA==", + "dependencies": { + "tslib": "^2.3.0" + }, + "optionalDependencies": { + "parse5": "^7.1.2" + }, + "peerDependencies": { + "@angular/common": "^19.0.0 || ^20.0.0", + "@angular/core": "^19.0.0 || ^20.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/cli": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-19.0.6.tgz", + "integrity": "sha512-ZEHhgRRVIdn10dbsAjB8TE9Co32hfuL9/im5Jcfa1yrn6KJefmigz6KN8Xu7FXMH5FkdqfQ11QpLBxJSPb9aww==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1900.6", + "@angular-devkit/core": "19.0.6", + "@angular-devkit/schematics": "19.0.6", + "@inquirer/prompts": "7.1.0", + "@listr2/prompt-adapter-inquirer": "2.0.18", + "@schematics/angular": "19.0.6", + "@yarnpkg/lockfile": "1.1.0", + "ini": "5.0.0", + "jsonc-parser": "3.3.1", + "listr2": "8.2.5", + "npm-package-arg": "12.0.0", + "npm-pick-manifest": "10.0.0", + "pacote": "20.0.0", + "resolve": "1.22.8", + "semver": "7.6.3", + "symbol-observable": "4.0.0", + "yargs": "17.7.2" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/cli/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular/cli/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular/cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/cli/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/common": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-19.0.5.tgz", + "integrity": "sha512-fFK+euCj1AjBHBCpj9VnduMSeqoMRhZZHbhPYiND7tucRRJ8vwGU0sYK2KI/Ko+fsrNIXL/0O4F36jVPl09Smg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.0.5", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/compiler": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-19.0.5.tgz", + "integrity": "sha512-S8ku5Ljp0kqX3shfmE9DVo09629jeYJSlBRGbj2Glb92dd+VQZPOz7KxqKRTwmAl7lQIV/+4Lr6G/GVTsoC4vg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.0.5" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + } + } + }, + "node_modules/@angular/compiler-cli": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.0.5.tgz", + "integrity": "sha512-KSzuWCTZlvJsoAenxM9cjTOzNM8mrFxDBInj0KVPz7QU83amGS4rcv1pWO/QGYQcErfskcN84TAdMegaRWWCmA==", + "dev": true, + "dependencies": { + "@babel/core": "7.26.0", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^4.0.0", + "convert-source-map": "^1.5.1", + "reflect-metadata": "^0.2.0", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^17.2.1" + }, + "bin": { + "ng-xi18n": "bundles/src/bin/ng_xi18n.js", + "ngc": "bundles/src/bin/ngc.js", + "ngcc": "bundles/ngcc/index.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/compiler": "19.0.5", + "typescript": ">=5.5 <5.7" + } + }, + "node_modules/@angular/compiler-cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/compiler-cli/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/core": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-19.0.5.tgz", + "integrity": "sha512-Ywc6sPO6G/Y1stfk3y/MallV/h0yzQ0vdOHRWueLrk5kD1DTdbolV4X03Cs3PuVvravgcSVE3nnuuHFuH32emQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.15.0" + } + }, + "node_modules/@angular/forms": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-19.0.5.tgz", + "integrity": "sha512-OhNFkfOoguqCDq07vNBV28FFrmTM8S11Z3Cd6PQZJJF9TgAtpV5KtF7A3eXBCN92W4pmqluomPjfK7YyImzIYQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.0.5", + "@angular/core": "19.0.5", + "@angular/platform-browser": "19.0.5", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.0.5.tgz", + "integrity": "sha512-41+Jo5DEil4Ifvv+UE/p1l9YJtYN+xfhx+/C9cahVgvV5D2q+givyK73d0Mnb6XOfe1q+hoV5lZ+XhQYp21//g==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/animations": "19.0.5", + "@angular/common": "19.0.5", + "@angular/core": "19.0.5" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/platform-browser-dynamic": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-19.0.5.tgz", + "integrity": "sha512-KKFdue/uJVxkWdrntRAXkz+ycp4nD3SuGOH5pPf2svCBxieuHuFlWDi+DYVuFSEpC/ICCmlhrtzIAm44A4qzzQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.0.5", + "@angular/compiler": "19.0.5", + "@angular/core": "19.0.5", + "@angular/platform-browser": "19.0.5" + } + }, + "node_modules/@angular/router": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-19.0.5.tgz", + "integrity": "sha512-6tNubVVj/rRyTg+OXjQxACfufvCLHAwDQtv9wqt6q/3OYSnysHTik3ho3FaFPwu7fXJ+6p9Rjzkh2VY9QMk4bw==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.0.5", + "@angular/core": "19.0.5", + "@angular/platform-browser": "19.0.5", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", + "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.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/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==", + "dev": true + }, + "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==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "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==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.26.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz", + "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", + "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", + "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.38.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.26.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", + "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.3", + "@babel/parser": "^7.26.3", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.3", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", + "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.26.3", + "@babel/types": "^7.26.3", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@dependents/detective-less": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@dependents/detective-less/-/detective-less-5.0.0.tgz", + "integrity": "sha512-D/9dozteKcutI5OdxJd8rU+fL6XgaaRg60sPPJWkT33OCiRfkCu5wO5B/yXTaaL2e6EB0lcCBGe5E0XscZCvvQ==", + "dev": true, + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", + "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", + "dev": true, + "engines": { + "node": ">=14.17.0" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz", + "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.2.tgz", + "integrity": "sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.2.tgz", + "integrity": "sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.2.tgz", + "integrity": "sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.0.4.tgz", + "integrity": "sha512-fYAKCAcGNMdfjL6hZTRUwkIByQ8EIZCXKrIQZH7XjADnN/xvRUhj8UdBbpC4zoUzvChhkSC/zRKaP/tDs3dZpg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.0.2.tgz", + "integrity": "sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/core": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.2.tgz", + "integrity": "sha512-bHd96F3ezHg1mf/J0Rb4CV8ndCN0v28kUlrHqP7+ECm1C/A+paB7Xh2lbMk6x+kweQC+rZOxM/YeKikzxco8bQ==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core/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==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.1.tgz", + "integrity": "sha512-xn9aDaiP6nFa432i68JCaL302FyL6y/6EG97nAtfIPnWZ+mWPgCMLGc4XZ2QQMsZtu9q3Jd5AzBPjXh10aX9kA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.4.tgz", + "integrity": "sha512-GYocr+BPyxKPxQ4UZyNMqZFSGKScSUc0Vk17II3J+0bDcgGsQm0KYQNooN1Q5iBfXsy3x/VWmHGh20QnzsaHwg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.9.tgz", + "integrity": "sha512-BXvGj0ehzrngHTPTDqUoDT3NXL8U0RxUk2zJm2A66RhCEIWdtU1v6GuUqNAgArW4PQ9CinqIWyHdQgdwOj06zQ==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.1.tgz", + "integrity": "sha512-nAXAHQndZcXB+7CyjIW3XuQZZHbQQ0q8LX6miY6bqAWwDzNa9JUioDBYrFmOUNIsuF08o1WT/m2gbBXvBhYVxg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.4.tgz", + "integrity": "sha512-DX7a6IXRPU0j8kr2ovf+QaaDiIf+zEKaZVzCWdLOTk7XigqSXvoh4cul7x68xp54WTQrgSnW7P1WBJDbyY3GhA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.4.tgz", + "integrity": "sha512-wiliQOWdjM8FnBmdIHtQV2Ca3S1+tMBUerhyjkRCv1g+4jSvEweGu9GCcvVEgKDhTBT15nrxvk5/bVrGUqSs1w==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.1.0.tgz", + "integrity": "sha512-5U/XiVRH2pp1X6gpNAjWOglMf38/Ys522ncEHIKT1voRUvSj/DQnR22OVxHnwu5S+rCFaUiPQ57JOtMFQayqYA==", + "dev": true, + "dependencies": { + "@inquirer/checkbox": "^4.0.2", + "@inquirer/confirm": "^5.0.2", + "@inquirer/editor": "^4.1.0", + "@inquirer/expand": "^4.0.2", + "@inquirer/input": "^4.0.2", + "@inquirer/number": "^3.0.2", + "@inquirer/password": "^4.0.2", + "@inquirer/rawlist": "^4.0.2", + "@inquirer/search": "^3.0.2", + "@inquirer/select": "^4.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.0.4.tgz", + "integrity": "sha512-IsVN2EZdNHsmFdKWx9HaXb8T/s3FlR/U1QPt9dwbSyPtjFbMTlW9CRFvnn0bm/QIsrMRD2oMZqrQpSWPQVbXXg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/search": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.4.tgz", + "integrity": "sha512-tSkJk2SDmC2MEdTIjknXWmCnmPr5owTs9/xjfa14ol1Oh95n6xW7SYn5fiPk4/vrJPys0ggSWiISdPze4LTa7A==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/select": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.0.4.tgz", + "integrity": "sha512-ZzYLuLoUzTIW9EJm++jBpRiTshGqS3Q1o5qOEQqgzaBlmdsjQr6pA4TUNkwu6OBYgM2mIRbCz6mUhFDfl/GF+w==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/figures": "^1.0.9", + "@inquirer/type": "^3.0.2", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.2.tgz", + "integrity": "sha512-ZhQ4TvhwHZF+lGhQ2O/rsjo80XoZR5/5qhOY3t6FJuX5XBg5Be8YzYTvaUGJnc12AUGI2nr4QSUE4PhKSigx7g==", + "dev": true, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/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==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/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==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/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==", + "dev": true + }, + "node_modules/@isaacs/cliui/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==", + "dev": true, + "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/@isaacs/cliui/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/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==", + "dev": true, + "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/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.1.tgz", + "integrity": "sha512-osjeBqMJ2lb/j/M8NCPjs1ylqWIcTRTycIhVB5pt6LgzgeRSb0YRZ7j9RfA8wIUrsr/medIuhVyonXRZWLyfdw==", + "dev": true, + "dependencies": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.5.0.tgz", + "integrity": "sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true + }, + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.18.tgz", + "integrity": "sha512-0hz44rAcrphyXcA8IS7EJ2SCoaBZD2u5goE8S/e+q/DL+dOGpqpcLidVOFeLG3VgML62SXmfRLAhWt0zL1oW4Q==", + "dev": true, + "dependencies": { + "@inquirer/type": "^1.5.5" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 8" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/@inquirer/type": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", + "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", + "dev": true, + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.1.5.tgz", + "integrity": "sha512-CGhsb0R5vE6mMNCoSfxHFD8QTvBHM51gs4DBeigTYHWnYv2V5YpJkC4rMo5qAAFifuUcc0+a8a3SIU0c9NrfNw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@napi-rs/nice": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.0.1.tgz", + "integrity": "sha512-zM0mVWSXE0a0h9aKACLwKmD6nHcRiKrPpCfvaKqG1CqDEyjEawId0ocXxVzPMCAm6kkWr2P025msfxXEnt8UGQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/nice-android-arm-eabi": "1.0.1", + "@napi-rs/nice-android-arm64": "1.0.1", + "@napi-rs/nice-darwin-arm64": "1.0.1", + "@napi-rs/nice-darwin-x64": "1.0.1", + "@napi-rs/nice-freebsd-x64": "1.0.1", + "@napi-rs/nice-linux-arm-gnueabihf": "1.0.1", + "@napi-rs/nice-linux-arm64-gnu": "1.0.1", + "@napi-rs/nice-linux-arm64-musl": "1.0.1", + "@napi-rs/nice-linux-ppc64-gnu": "1.0.1", + "@napi-rs/nice-linux-riscv64-gnu": "1.0.1", + "@napi-rs/nice-linux-s390x-gnu": "1.0.1", + "@napi-rs/nice-linux-x64-gnu": "1.0.1", + "@napi-rs/nice-linux-x64-musl": "1.0.1", + "@napi-rs/nice-win32-arm64-msvc": "1.0.1", + "@napi-rs/nice-win32-ia32-msvc": "1.0.1", + "@napi-rs/nice-win32-x64-msvc": "1.0.1" + } + }, + "node_modules/@napi-rs/nice-darwin-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.1.tgz", + "integrity": "sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ngtools/webpack": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-19.0.6.tgz", + "integrity": "sha512-eWrIb0tS1CK6+JvFS4GgTD4fN9TtmApKrlaj3pPQXKXKKd42361ec85fuQQXdb4G8eEEq0vyd/bn4NJllh/3vw==", + "dev": true, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^19.0.0", + "typescript": ">=5.5 <5.7", + "webpack": "^5.54.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz", + "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/@npmcli/fs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz", + "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-6.0.1.tgz", + "integrity": "sha512-BBWMMxeQzalmKadyimwb2/VVQyJB01PH0HhVSNLHNBDZN/M/h/02P6f8fxedIiFhpMj11SO9Ep5tKTBE7zL2nw==", + "dev": true, + "dependencies": { + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-3.0.0.tgz", + "integrity": "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q==", + "dev": true, + "dependencies": { + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-6.1.0.tgz", + "integrity": "sha512-t6G+6ZInT4X+tqj2i+wlLIeCKnKOTuz9/VFYDtj+TGTur5q7sp/OYrQA19LdBbWfXDOi0Y4jtedV6xtB8zQ9ug==", + "dev": true, + "dependencies": { + "@npmcli/git": "^6.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "normalize-package-data": "^7.0.0", + "proc-log": "^5.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/package-json/node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", + "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-8.0.2.tgz", + "integrity": "sha512-/bNJhjc+o6qL+Dwz/bqfTQClkEO5nTQ1ZEcdCkAQjhkZMHIh22LPG7fNh1enJP1NKWDqYiiABnjFCY7E0zHYtQ==", + "dev": true, + "dependencies": { + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-3.0.0.tgz", + "integrity": "sha512-/1uFzjVcfzqrgCeGW7+SZ4hv0qLWmKXVzFahZGJ6QuJBj6Myt9s17+JL86i76NV9YSnJRcGXJYQbAU0rn1YTCQ==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-9.0.2.tgz", + "integrity": "sha512-cJXiUlycdizQwvqE1iaAb4VRUM3RX09/8q46zjvy+ct9GhfZRWd7jXYVc1tn/CfRlGPVkX/u4sstRlepsm7hfw==", + "dev": true, + "dependencies": { + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "node-gyp": "^11.0.0", + "proc-log": "^5.0.0", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.0.tgz", + "integrity": "sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.0", + "@parcel/watcher-darwin-arm64": "2.5.0", + "@parcel/watcher-darwin-x64": "2.5.0", + "@parcel/watcher-freebsd-x64": "2.5.0", + "@parcel/watcher-linux-arm-glibc": "2.5.0", + "@parcel/watcher-linux-arm-musl": "2.5.0", + "@parcel/watcher-linux-arm64-glibc": "2.5.0", + "@parcel/watcher-linux-arm64-musl": "2.5.0", + "@parcel/watcher-linux-x64-glibc": "2.5.0", + "@parcel/watcher-linux-x64-musl": "2.5.0", + "@parcel/watcher-win32-arm64": "2.5.0", + "@parcel/watcher-win32-ia32": "2.5.0", + "@parcel/watcher-win32-x64": "2.5.0" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.0.tgz", + "integrity": "sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@parcel/watcher/node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "optional": true + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/plugin-json": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz", + "integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.1.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.26.0.tgz", + "integrity": "sha512-wbgkYDHcdWW+NqP2mnf2NOuEbOLzDblalrOWcPyY6+BRbVhliavon15UploG7PpBRQ2bZJnbmh8o3yLoBvDIHA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/wasm-node": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/wasm-node/-/wasm-node-4.29.1.tgz", + "integrity": "sha512-AOtO2Y+XzElJfmJgAECOgbutmKAK5XcKH7CipGDQDBMfLY04ezEoCHWEpmoX5L7/WH3k17rXMCClNiwDbWW+mw==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/@schematics/angular": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-19.0.6.tgz", + "integrity": "sha512-HicclmbW/+mlljU7a4PzbyIWG+7tognoL5LsgMFJQUDzJXHNjRt1riL0vk57o8Pcprnz9FheeWZXO1KRhXkQuw==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "19.0.6", + "@angular-devkit/schematics": "19.0.6", + "jsonc-parser": "3.3.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { + "version": "19.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.6.tgz", + "integrity": "sha512-WUWJhzQDsovfMY6jtb9Ktz/5sJszsaErj+XV2aXab85f1OweI/Iv2urPZnJwUSilvVN5Ok/fy3IJ6SuihK4Ceg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@schematics/angular/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@schematics/angular/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@schematics/angular/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@sentry-internal/tracing": { + "version": "7.84.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.84.0.tgz", + "integrity": "sha512-y9bGYA0OM6PEREfd+nk4UURZy29tpIw+7vQwpxWfEVs2fqq0/5TBFX/tKFb8AKUI9lVM8v0bcF0bNSCnuPQZHQ==", + "dev": true, + "dependencies": { + "@sentry/core": "7.84.0", + "@sentry/types": "7.84.0", + "@sentry/utils": "7.84.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/core": { + "version": "7.84.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.84.0.tgz", + "integrity": "sha512-tbuwunbBx2kSex15IHCqHDnrMfIlqPc6w/76fwkGqokz3oh9GSEGlLICwmBWL8AypWimUg13IDtFpD0TJTriWA==", + "dev": true, + "dependencies": { + "@sentry/types": "7.84.0", + "@sentry/utils": "7.84.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/node": { + "version": "7.84.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.84.0.tgz", + "integrity": "sha512-Xm3fIXT3TZOQi+6uQBavI8iOehD3PkY7v0y3hog0d4lQTH88vQK9BBsI+jZEq81Em+RG/u7vZNiFo6YMTnWF7Q==", + "dev": true, + "dependencies": { + "@sentry-internal/tracing": "7.84.0", + "@sentry/core": "7.84.0", + "@sentry/types": "7.84.0", + "@sentry/utils": "7.84.0", + "https-proxy-agent": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/node/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==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@sentry/node/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==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sentry/types": { + "version": "7.84.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.84.0.tgz", + "integrity": "sha512-VqGLIF3JOUrk7yIXjLXJvAORkZL1e3dDX0Q1okRehwyt/5CRE+mdUTeJZkBo9P9mBwgMyvtwklzOGGrzjb4eMA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/utils": { + "version": "7.84.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.84.0.tgz", + "integrity": "sha512-qdUVuxnRBvaf05AU+28R+xYtZmi/Ymf8os3Njq9g4XuA+QEkZLbzmIpRK5W9Ja7vUtjOeg29Xgg43A8znde9LQ==", + "dev": true, + "dependencies": { + "@sentry/types": "7.84.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sigstore/bundle": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-3.0.0.tgz", + "integrity": "sha512-XDUYX56iMPAn/cdgh/DTJxz5RWmqKV4pwvUAEKEWJl+HzKdCd/24wUa9JYNMlDSCb7SUHAdtksxYX779Nne/Zg==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-2.0.0.tgz", + "integrity": "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.2.tgz", + "integrity": "sha512-c6B0ehIWxMI8wiS/bj6rHMPqeFvngFV7cDU/MY+B16P9Z3Mp9k8L93eYZ7BYzSickzuqAQqAq0V956b3Ju6mLw==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-3.0.0.tgz", + "integrity": "sha512-UjhDMQOkyDoktpXoc5YPJpJK6IooF2gayAr5LvXI4EL7O0vd58okgfRcxuaH+YTdhvb5aa1Q9f+WJ0c2sVuYIw==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^14.0.1", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-3.0.0.tgz", + "integrity": "sha512-9Xxy/8U5OFJu7s+OsHzI96IX/OzjF/zj0BSSaWhgJgTqtlBhQIV2xdrQI5qxLD7+CWWDepadnXAxzaZ3u9cvRw==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2", + "tuf-js": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-2.0.0.tgz", + "integrity": "sha512-Ggtq2GsJuxFNUvQzLoXqRwS4ceRfLAJnrIHUDrzAD0GgnOhwujJkKkxM/s5Bako07c3WtAs/sZo5PJq7VHjeDg==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", + "dev": true + }, + "node_modules/@ts-graphviz/adapter": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@ts-graphviz/adapter/-/adapter-2.0.6.tgz", + "integrity": "sha512-kJ10lIMSWMJkLkkCG5gt927SnGZcBuG0s0HHswGzcHTgvtUe7yk5/3zTEr0bafzsodsOq5Gi6FhQeV775nC35Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ts-graphviz" + } + ], + "dependencies": { + "@ts-graphviz/common": "^2.1.5" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ts-graphviz/ast": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@ts-graphviz/ast/-/ast-2.0.6.tgz", + "integrity": "sha512-JbOnw6+Pm+C9jRQlNV+qJG0/VTan4oCeZ0sClm++SjaaMBJ0q86O13i6wbcWKY2x8kKt9GP2hVCgM/p/BXtXWQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ts-graphviz" + } + ], + "dependencies": { + "@ts-graphviz/common": "^2.1.5" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ts-graphviz/common": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@ts-graphviz/common/-/common-2.1.5.tgz", + "integrity": "sha512-S6/9+T6x8j6cr/gNhp+U2olwo1n0jKj/682QVqsh7yXWV6ednHYqxFw0ZsY3LyzT0N8jaZ6jQY9YD99le3cmvg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ts-graphviz" + } + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@ts-graphviz/core": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@ts-graphviz/core/-/core-2.0.6.tgz", + "integrity": "sha512-0hvrluFirC0ph3Dn2o1B0O1fI2n7Hre1HlScfmRcO6DDDq/05Vizg5UMI0LfvkJulLuz80RPjUHluh+QfBUBKw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ts-graphviz" + } + ], + "dependencies": { + "@ts-graphviz/ast": "^2.0.6", + "@ts-graphviz/common": "^2.1.5" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-3.0.1.tgz", + "integrity": "sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==", + "dev": true, + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@tufjs/models/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true + }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.44.8", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.8.tgz", + "integrity": "sha512-4K8GavROwhrYl2QXDXm0Rv9epkA8GBFu0EI+XrrnnuCl7u8CWBRusX7fXJfanhZTDWSAL24gDI/UqXyUM0Injw==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.2.tgz", + "integrity": "sha512-vluaspfvWEtE4vcSDlKRNer52DvOGrB2xv6diXy6UKyKW0lqZiWHGNApSyxOv+8DE5Z27IzVvE7hNkxg7EXIcg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/express/node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/jasmine": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.4.tgz", + "integrity": "sha512-px7OMFO/ncXxixDe1zR13V1iycqWae0MxTaw62RpFlksUi5QuNWgQJFkTQjIOvrmutJbI7Fp2Y2N1F6D2R4G6w==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.12.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.13.tgz", + "integrity": "sha512-gBGeanV41c1L171rR7wjbMiEpEI/l5XFQdLLfhr/REwpgDy/4U8y89+i8kRiLzDyZdOkXh+cRaTetUnCYutoXA==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.9.17", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", + "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.1.0.tgz", + "integrity": "sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A==", + "dev": true, + "engines": { + "node": ">=14.6.0" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz", + "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/shared": "3.5.13", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz", + "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==", + "dev": true, + "dependencies": { + "@vue/compiler-core": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz", + "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/compiler-core": "3.5.13", + "@vue/compiler-dom": "3.5.13", + "@vue/compiler-ssr": "3.5.13", + "@vue/shared": "3.5.13", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.11", + "postcss": "^8.4.48", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz", + "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==", + "dev": true, + "dependencies": { + "@vue/compiler-dom": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz", + "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==", + "dev": true + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/app-module-path": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ast-module-types": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-6.0.0.tgz", + "integrity": "sha512-LFRg7178Fw5R4FAEwZxVqiRI8IxSM+Ay2UBrHoCerXNme+kMMMfz7T3xDGV/c2fer87hcrtgJGsnSOfUrPK6ng==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/async-each-series": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-0.1.1.tgz", + "integrity": "sha512-p4jj6Fws4Iy2m0iCmI2am2ZNZCgbdgE+P8F/8csmn2vx7ixXrO2zGcuNsD46X5uZSVecmkEy/M06X2vG8KD6dQ==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "dev": true + }, + "node_modules/babel-loader": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", + "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", + "dev": true, + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.3", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.3" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "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==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true, + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/beasties": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.1.0.tgz", + "integrity": "sha512-+Ssscd2gVG24qRNC+E2g88D+xsQW4xwakWtKAiGEQ3Pw54/FGdyo9RrfxhGhEv6ilFVbB7r3Lgx+QnAxnSpECw==", + "dev": true, + "dependencies": { + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "htmlparser2": "^9.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-media-query-parser": "^0.2.3" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/body-parser/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/bonjour-service": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "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==", + "dev": true + }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-sync": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-3.0.2.tgz", + "integrity": "sha512-PC9c7aWJFVR4IFySrJxOqLwB9ENn3/TaXCXtAa0SzLwocLN3qMjN+IatbjvtCX92BjNXsY6YWg9Eb7F3Wy255g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "browser-sync-client": "^3.0.2", + "browser-sync-ui": "^3.0.2", + "bs-recipes": "1.3.4", + "chalk": "4.1.2", + "chokidar": "^3.5.1", + "connect": "3.6.6", + "connect-history-api-fallback": "^1", + "dev-ip": "^1.0.1", + "easy-extender": "^2.3.4", + "eazy-logger": "^4.0.1", + "etag": "^1.8.1", + "fresh": "^0.5.2", + "fs-extra": "3.0.1", + "http-proxy": "^1.18.1", + "immutable": "^3", + "micromatch": "^4.0.2", + "opn": "5.3.0", + "portscanner": "2.2.0", + "raw-body": "^2.3.2", + "resp-modifier": "6.0.2", + "rx": "4.1.0", + "send": "0.16.2", + "serve-index": "1.9.1", + "serve-static": "1.13.2", + "server-destroy": "1.0.1", + "socket.io": "^4.4.1", + "ua-parser-js": "^1.0.33", + "yargs": "^17.3.1" + }, + "bin": { + "browser-sync": "dist/bin.js" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/browser-sync-client": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-3.0.2.tgz", + "integrity": "sha512-tBWdfn9L0wd2Pjuz/NWHtNEKthVb1Y67vg8/qyGNtCqetNz5lkDkFnrsx5UhPNPYUO8vci50IWC/BhYaQskDiQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "etag": "1.8.1", + "fresh": "0.5.2", + "mitt": "^1.1.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/browser-sync-ui": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-3.0.2.tgz", + "integrity": "sha512-V3FwWAI+abVbFLTyJjXJlCMBwjc3GXf/BPGfwO2fMFACWbIGW9/4SrBOFYEOOtqzCjQE0Di+U3VIb7eES4omNA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "async-each-series": "0.1.1", + "chalk": "4.1.2", + "connect-history-api-fallback": "^1", + "immutable": "^3", + "server-destroy": "1.0.1", + "socket.io-client": "^4.4.1", + "stream-throttle": "^0.1.3" + } + }, + "node_modules/browser-sync-ui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/browser-sync-ui/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/browser-sync-ui/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==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/browser-sync-ui/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==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/browser-sync-ui/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-sync-ui/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-sync/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/browser-sync/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/browser-sync/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==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/browser-sync/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==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/browser-sync/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-sync/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz", + "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==", + "dev": true, + "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.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-recipes": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz", + "integrity": "sha512-BXvDkqhDNxXEjeGM8LFkSbR+jzmP/CYpCiVKYn+soB1dDldeU15EBNDkwVXndKuX35wnNUaPd0qSoQEAkmQtMw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz", + "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^4.0.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001690", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", + "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", + "dev": true, + "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/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "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" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "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/cli-truncate/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cliui/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==", + "dev": true + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", + "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.0.2", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/connect": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", + "integrity": "sha512-OO7axMmPpu/2XuX1+2Yrg0ddju31B6xLZMWkJ5rYBu4YRmRVlOjvlY6kw2FJKiAzyxGwnrDUAG4s1Pf0sbBMCQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.0", + "parseurl": "~1.3.2", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "dev": true, + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", + "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", + "dev": true, + "dependencies": { + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.1", + "globby": "^14.0.0", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/core-js-compat": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", + "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==", + "dev": true, + "dependencies": { + "browserslist": "^4.24.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cosmiconfig/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==", + "dev": true + }, + "node_modules/cosmiconfig/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==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/coveralls": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz", + "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==", + "dev": true, + "dependencies": { + "js-yaml": "^3.13.1", + "lcov-parse": "^1.0.0", + "log-driver": "^1.2.7", + "minimist": "^1.2.5", + "request": "^2.88.2" + }, + "bin": { + "coveralls": "bin/coveralls.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cpr": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cpr/-/cpr-3.0.1.tgz", + "integrity": "sha512-Xch4PXQ/KC8lJ+KfJ9JI6eG/nmppLrPPWg5Q+vh65Qr9EjuJEubxh/H/Le1TmCZ7+Xv7iJuNRqapyOFZB+wsxA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.5", + "minimist": "^1.2.0", + "mkdirp": "~0.5.1", + "rimraf": "^2.5.4" + }, + "bin": { + "cpr": "bin/cpr" + } + }, + "node_modules/cpr/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "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==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", + "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", + "dev": true, + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "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==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", + "dev": true + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dependency-graph": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-1.0.0.tgz", + "integrity": "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/dependency-tree": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/dependency-tree/-/dependency-tree-11.0.1.tgz", + "integrity": "sha512-eCt7HSKIC9NxgIykG2DRq3Aewn9UhVS14MB3rEn6l/AsEI1FBg6ZGSlCU0SZ6Tjm2kkhj6/8c2pViinuyKELhg==", + "dev": true, + "dependencies": { + "commander": "^12.0.0", + "filing-cabinet": "^5.0.1", + "precinct": "^12.0.2", + "typescript": "^5.4.5" + }, + "bin": { + "dependency-tree": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/dependency-tree/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/detective-amd": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-6.0.0.tgz", + "integrity": "sha512-NTqfYfwNsW7AQltKSEaWR66hGkTeD52Kz3eRQ+nfkA9ZFZt3iifRCWh+yZ/m6t3H42JFwVFTrml/D64R2PAIOA==", + "dev": true, + "dependencies": { + "ast-module-types": "^6.0.0", + "escodegen": "^2.1.0", + "get-amd-module-type": "^6.0.0", + "node-source-walk": "^7.0.0" + }, + "bin": { + "detective-amd": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-cjs": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detective-cjs/-/detective-cjs-6.0.0.tgz", + "integrity": "sha512-R55jTS6Kkmy6ukdrbzY4x+I7KkXiuDPpFzUViFV/tm2PBGtTCjkh9ZmTuJc1SaziMHJOe636dtiZLEuzBL9drg==", + "dev": true, + "dependencies": { + "ast-module-types": "^6.0.0", + "node-source-walk": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-es6": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detective-es6/-/detective-es6-5.0.0.tgz", + "integrity": "sha512-NGTnzjvgeMW1khUSEXCzPDoraLenWbUjCFjwxReH+Ir+P6LGjYtaBbAvITWn2H0VSC+eM7/9LFOTAkrta6hNYg==", + "dev": true, + "dependencies": { + "node-source-walk": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-postcss": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/detective-postcss/-/detective-postcss-7.0.0.tgz", + "integrity": "sha512-pSXA6dyqmBPBuERpoOKKTUUjQCZwZPLRbd1VdsTbt6W+m/+6ROl4BbE87yQBUtLoK7yX8pvXHdKyM/xNIW9F7A==", + "dev": true, + "dependencies": { + "is-url": "^1.2.4", + "postcss-values-parser": "^6.0.2" + }, + "engines": { + "node": "^14.0.0 || >=16.0.0" + }, + "peerDependencies": { + "postcss": "^8.4.38" + } + }, + "node_modules/detective-sass": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detective-sass/-/detective-sass-6.0.0.tgz", + "integrity": "sha512-h5GCfFMkPm4ZUUfGHVPKNHKT8jV7cSmgK+s4dgQH4/dIUNh9/huR1fjEQrblOQNDalSU7k7g+tiW9LJ+nVEUhg==", + "dev": true, + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-scss": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detective-scss/-/detective-scss-5.0.0.tgz", + "integrity": "sha512-Y64HyMqntdsCh1qAH7ci95dk0nnpA29g319w/5d/oYcHolcGUVJbIhOirOFjfN1KnMAXAFm5FIkZ4l2EKFGgxg==", + "dev": true, + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-stylus": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detective-stylus/-/detective-stylus-5.0.0.tgz", + "integrity": "sha512-KMHOsPY6aq3196WteVhkY5FF+6Nnc/r7q741E+Gq+Ax9mhE2iwj8Hlw8pl+749hPDRDBHZ2WlgOjP+twIG61vQ==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-typescript": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/detective-typescript/-/detective-typescript-13.0.0.tgz", + "integrity": "sha512-tcMYfiFWoUejSbvSblw90NDt76/4mNftYCX0SMnVRYzSXv8Fvo06hi4JOPdNvVNxRtCAKg3MJ3cBJh+ygEMH+A==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "^7.6.0", + "ast-module-types": "^6.0.0", + "node-source-walk": "^7.0.0" + }, + "engines": { + "node": "^14.14.0 || >=16.0.0" + }, + "peerDependencies": { + "typescript": "^5.4.4" + } + }, + "node_modules/detective-vue2": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detective-vue2/-/detective-vue2-2.1.0.tgz", + "integrity": "sha512-IHQVhwk7dKaJ+GHBsL27mS9NRO1/vLZJPSODqtJgKquij0/UL8NvrbXbADbYeTkwyh1ReW/v9u9IRyEO5dvGZg==", + "dev": true, + "dependencies": { + "@dependents/detective-less": "^5.0.0", + "@vue/compiler-sfc": "^3.5.12", + "detective-es6": "^5.0.0", + "detective-sass": "^6.0.0", + "detective-scss": "^5.0.0", + "detective-stylus": "^5.0.0", + "detective-typescript": "^13.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "typescript": "^5.4.4" + } + }, + "node_modules/dev-ip": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz", + "integrity": "sha512-LmVkry/oDShEgSZPNgqCIp2/TlqtExeGmymru3uCELnfyjY11IzpAproLYs+1X88fXO6DBoYP3ul2Xo2yz2j6A==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "dev-ip": "lib/dev-ip.js" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "node_modules/di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", + "dev": true, + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/easy-extender": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz", + "integrity": "sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "lodash": "^4.17.10" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/eazy-logger": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-4.0.1.tgz", + "integrity": "sha512-2GSFtnnC6U4IEKhEI7+PvdxrmjJ04mdsj3wHZTFiw0tUtG4HCWzTr13ZYTk8XOGnA1xQMaDljoBOYlk3D/MMSw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "chalk": "4.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eazy-logger/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eazy-logger/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eazy-logger/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==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eazy-logger/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==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/eazy-logger/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eazy-logger/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.5.75", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.75.tgz", + "integrity": "sha512-Lf3++DumRE/QmweGjU+ZcKqQ+3bKkU/qjaKYhIJKEOhgIO9Xs6IiAQFkfFoj+RhgDk4LUeNsLo6plExHqSyu6Q==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/engine.io": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz", + "integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==", + "dev": true, + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-client": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz", + "integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz", + "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", + "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", + "dev": true + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "devOptional": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "dev": true + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz", + "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.0", + "@esbuild/android-arm": "0.24.0", + "@esbuild/android-arm64": "0.24.0", + "@esbuild/android-x64": "0.24.0", + "@esbuild/darwin-arm64": "0.24.0", + "@esbuild/darwin-x64": "0.24.0", + "@esbuild/freebsd-arm64": "0.24.0", + "@esbuild/freebsd-x64": "0.24.0", + "@esbuild/linux-arm": "0.24.0", + "@esbuild/linux-arm64": "0.24.0", + "@esbuild/linux-ia32": "0.24.0", + "@esbuild/linux-loong64": "0.24.0", + "@esbuild/linux-mips64el": "0.24.0", + "@esbuild/linux-ppc64": "0.24.0", + "@esbuild/linux-riscv64": "0.24.0", + "@esbuild/linux-s390x": "0.24.0", + "@esbuild/linux-x64": "0.24.0", + "@esbuild/netbsd-x64": "0.24.0", + "@esbuild/openbsd-arm64": "0.24.0", + "@esbuild/openbsd-x64": "0.24.0", + "@esbuild/sunos-x64": "0.24.0", + "@esbuild/win32-arm64": "0.24.0", + "@esbuild/win32-ia32": "0.24.0", + "@esbuild/win32-x64": "0.24.0" + } + }, + "node_modules/esbuild-wasm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.24.0.tgz", + "integrity": "sha512-xhNn5tL1AhkPg4ft59yXT6FkwKXiPSYyz1IeinJHUJpjvOHOIPvdmFQc0pGdjxlKSbzZc2mNmtVOWAR1EF/JAg==", + "dev": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "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==", + "dev": true + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/express/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/express/node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/express/node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dev": true, + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "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==", + "dev": true, + "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/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-uri": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/filing-cabinet": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/filing-cabinet/-/filing-cabinet-5.0.2.tgz", + "integrity": "sha512-RZlFj8lzyu6jqtFBeXNqUjjNG6xm+gwXue3T70pRxw1W40kJwlgq0PSWAmh0nAnn5DHuBIecLXk9+1VKS9ICXA==", + "dev": true, + "dependencies": { + "app-module-path": "^2.2.0", + "commander": "^12.0.0", + "enhanced-resolve": "^5.16.0", + "module-definition": "^6.0.0", + "module-lookup-amd": "^9.0.1", + "resolve": "^1.22.8", + "resolve-dependency-path": "^4.0.0", + "sass-lookup": "^6.0.1", + "stylus-lookup": "^6.0.0", + "tsconfig-paths": "^4.2.0", + "typescript": "^5.4.4" + }, + "bin": { + "filing-cabinet": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/filing-cabinet/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha512-ejnvM9ZXYzp6PUPUyQBMBf0Co5VX2gr5H2VQe2Ui2jWXNlxv+PYZo8wpAymJNJdLsG1R4p+M4aynF8KuoUEwRw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.3.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dev": true, + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/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==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", + "integrity": "sha512-V3Z3WZWVUYd8hoCL5xfXJCaHWYzmtwW5XWYSlLgERi8PWd8bx1kUHUk8L1BT57e49oKnDDD180mjfrHc1yA9rg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "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==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-amd-module-type": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-amd-module-type/-/get-amd-module-type-6.0.0.tgz", + "integrity": "sha512-hFM7oivtlgJ3d6XWD6G47l8Wyh/C6vFw5G24Kk1Tbq85yh5gcM8Fne5/lFhiuxB+RT6+SI7I1ThB9lG4FBh3jw==", + "dev": true, + "dependencies": { + "ast-module-types": "^6.0.0", + "node-source-walk": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", + "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "function-bind": "^1.1.2", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "dev": true, + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "dev": true, + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gonzales-pe": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "gonzales": "bin/gonzales.js" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/har-validator/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/har-validator/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.0.2.tgz", + "integrity": "sha512-sYKnA7eGln5ov8T8gnYlkSOxFJvywzEx9BueN6xo/GKO8PGiI6uK6xx+DIGe45T3bdVjLAQDQW1aicT8z8JwQg==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "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==", + "dev": true + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-middleware": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.3.tgz", + "integrity": "sha512-usY0HG5nyDUwtqpiZdETNbmKtw3QQ1jwYFZ9wi5iHzX2BcILwQKtYDJPo7XHTsu5Z0B2Hj3W9NNnbd+AjFWjqg==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.15", + "debug": "^4.3.6", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.3", + "is-plain-object": "^5.0.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-middleware/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-7.0.0.tgz", + "integrity": "sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ==", + "dev": true, + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ignore-walk/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "dev": true, + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immutable": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", + "integrity": "sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/injection-js": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/injection-js/-/injection-js-2.4.0.tgz", + "integrity": "sha512-6jiJt0tCAo9zjHbcwLiPL+IuNe9SQ6a9g0PEzafThW3fOQi0mrmiJGBJvDD6tmhPh8cQHIQtCOrJuBfQME4kPA==", + "dev": true, + "dependencies": { + "tslib": "^2.0.0" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ip-address/node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, + "node_modules/ip-address/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "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-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "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": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "dev": true, + "engines": { + "node": ">=16" + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-like": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz", + "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "lodash.isfinite": "^3.3.2" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true + }, + "node_modules/is-url-superb": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-url-superb/-/is-url-superb-4.0.0.tgz", + "integrity": "sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jasmine-core": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.4.0.tgz", + "integrity": "sha512-T4fio3W++llLd7LGSGsioriDHgWyhoL6YTu4k37uwJLF7DzOzspz7mNxRoM3cQdLWtL/ebazQpIf/yZGJx/gzg==", + "dev": true + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha512-oBko6ZHlubVB5mRFkur5vgYR1UyqX+S6Y/oCfLhqNdcc2fYFlDpIoNc7AfKS1KOGcnNAkvsr0grLck9ANM815w==", + "dev": true, + "optional": true, + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/karma": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.2.tgz", + "integrity": "sha512-C6SU/53LB31BEgRg+omznBEMY4SjHU3ricV6zBcAe1EeILKkeScr+fZXtaI5WyDbkVowJxxAI6h73NcFPmXolQ==", + "dev": true, + "dependencies": { + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.4.1", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-chrome-launcher": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", + "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", + "dev": true, + "dependencies": { + "which": "^1.2.1" + } + }, + "node_modules/karma-chrome-launcher/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/karma-coverage": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.1.tgz", + "integrity": "sha512-yj7hbequkQP2qOSb20GuNSIyE//PgJWHwC2IydLE6XRtsnaflv+/OSGNssPjobYUlhVVagy99TQpqUt3vAUG7A==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.0.5", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/karma-jasmine": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", + "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==", + "dev": true, + "dependencies": { + "jasmine-core": "^4.1.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "karma": "^6.0.0" + } + }, + "node_modules/karma-jasmine-html-reporter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.1.0.tgz", + "integrity": "sha512-sPQE1+nlsn6Hwb5t+HHwyy0A1FNCVKuL1192b+XNauMYWThz2kweiBVW1DqloRpVvZIJkIoHVB7XRpK78n1xbQ==", + "dev": true, + "peerDependencies": { + "jasmine-core": "^4.0.0 || ^5.0.0", + "karma": "^6.0.0", + "karma-jasmine": "^5.0.0" + } + }, + "node_modules/karma-jasmine/node_modules/jasmine-core": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.0.tgz", + "integrity": "sha512-O236+gd0ZXS8YAjFx8xKaJ94/erqUliEkJTDedyE7iHvv4ZVqi+q+8acJxu05/WJDKm512EUNn809In37nWlAQ==", + "dev": true + }, + "node_modules/karma-mocha-reporter": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz", + "integrity": "sha512-Hr6nhkIp0GIJJrvzY8JFeHpQZNseuIakGac4bpw8K1+5F0tLb6l7uvXRa8mt2Z+NVwYgCct4QAfp2R2QP6o00w==", + "dev": true, + "dependencies": { + "chalk": "^2.1.0", + "log-symbols": "^2.1.0", + "strip-ansi": "^4.0.0" + }, + "peerDependencies": { + "karma": ">=0.13" + } + }, + "node_modules/karma-mocha-reporter/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/karma-mocha-reporter/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/karma-source-map-support": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", + "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", + "dev": true, + "dependencies": { + "source-map-support": "^0.5.5" + } + }, + "node_modules/karma/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/karma/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/karma/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/karma/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==", + "dev": true + }, + "node_modules/karma/node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/karma/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/karma/node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/karma/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/karma/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/karma/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/karma/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/karma/node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/karma/node_modules/ua-parser-js": { + "version": "0.7.37", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.37.tgz", + "integrity": "sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "engines": { + "node": "*" + } + }, + "node_modules/karma/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/karma/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/karma/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/launch-editor": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/lcov-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", + "integrity": "sha512-aprLII/vPzuQvYZnDRU78Fns9I2Ag3gi4Ipga/hxnVMCZC8DnR2nI7XBqrPoywGfxqIx/DgarGvDJZAD3YBTgQ==", + "dev": true, + "bin": { + "lcov-parse": "bin/cli.js" + } + }, + "node_modules/less": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/less/-/less-4.2.0.tgz", + "integrity": "sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==", + "dev": true, + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less-loader": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-12.2.0.tgz", + "integrity": "sha512-MYUxjSQSBUQmowc0l5nPieOYwMzGPUaTzB6inNW/bdPEG9zOL3eAAD1Qw5ZxSPk7we5dMojHwNODYMV1hq4EVg==", + "dev": true, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "less": "^3.5.0 || ^4.0.0", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/less/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/less/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/less/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/license-checker": { + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/license-checker/-/license-checker-25.0.1.tgz", + "integrity": "sha512-mET5AIwl7MR2IAKYYoVBBpV0OnkKQ1xGj2IMMeEFIs42QAkEVjRtFZGWmQ28WeU7MP779iAgOaOy93Mn44mn6g==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "debug": "^3.1.0", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "read-installed": "~4.0.3", + "semver": "^5.5.0", + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0", + "spdx-satisfies": "^4.0.0", + "treeify": "^1.1.0" + }, + "bin": { + "license-checker": "bin/license-checker" + } + }, + "node_modules/license-checker/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/license-checker/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/license-webpack-plugin": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", + "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==", + "dev": true, + "dependencies": { + "webpack-sources": "^3.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-sources": { + "optional": true + } + } + }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/listr2": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", + "integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/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==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "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/listr2/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/lmdb": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.1.5.tgz", + "integrity": "sha512-46Mch5Drq+A93Ss3gtbg+Xuvf5BOgIuvhKDWoGa3HcPHI6BL2NCOkRdSx1D4VfzwrxhnsjbyIVsLRlQHu6URvw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "msgpackr": "^1.11.2", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.2.2", + "ordered-binary": "^1.5.3", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "3.1.5", + "@lmdb/lmdb-darwin-x64": "3.1.5", + "@lmdb/lmdb-linux-arm": "3.1.5", + "@lmdb/lmdb-linux-arm64": "3.1.5", + "@lmdb/lmdb-linux-x64": "3.1.5", + "@lmdb/lmdb-win32-x64": "3.1.5" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/lodash.isfinite": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", + "integrity": "sha512-7FGG40uhC8Mm633uKW1r58aElFlBlxCrg9JfSi3P6aYiWmfiWF0PgMd86ZUsxE5GwWPdHoS2+48bwTh2VPkIQA==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "dev": true, + "engines": { + "node": ">=0.8.6" + } + }, + "node_modules/log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/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==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/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==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "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/log-update/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/log4js": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "dev": true, + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/madge": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/madge/-/madge-8.0.0.tgz", + "integrity": "sha512-9sSsi3TBPhmkTCIpVQF0SPiChj1L7Rq9kU2KDG1o6v2XH9cCw086MopjVCD+vuoL5v8S77DTbVopTO8OUiQpIw==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "commander": "^7.2.0", + "commondir": "^1.0.1", + "debug": "^4.3.4", + "dependency-tree": "^11.0.0", + "ora": "^5.4.1", + "pluralize": "^8.0.0", + "pretty-ms": "^7.0.1", + "rc": "^1.2.8", + "stream-to-array": "^2.3.0", + "ts-graphviz": "^2.1.2", + "walkdir": "^0.4.1" + }, + "bin": { + "madge": "bin/cli.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "individual", + "url": "https://www.paypal.me/pahen" + }, + "peerDependencies": { + "typescript": "^5.4.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/madge/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/madge/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/madge/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/madge/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==", + "dev": true + }, + "node_modules/madge/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/madge/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/magic-string": { + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-fetch-happen": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", + "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==", + "dev": true, + "dependencies": { + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/make-fetch-happen/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/matcher/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.15.1.tgz", + "integrity": "sha512-ufCzgFwiVnR6R9cCYuvwznJdhdYXEvFl0hpnM4cCtVaVkHuqBR+6fo2sqt1SSMdp+uiHw9GyPZr3OMM5tqjSmQ==", + "dev": true, + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.3.0", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", + "dev": true, + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "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==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.0.tgz", + "integrity": "sha512-2v6aXUXwLP1Epd/gc32HAMIWoczx+fZwEPRHm/VwtrJzRGwR1qGZXEYV3Zp8ZjjbwaZhMrM6uHV4KVkk+XCc2w==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/minizlib/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/minizlib/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minizlib/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minizlib/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mitt": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.2.0.tgz", + "integrity": "sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/module-definition": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/module-definition/-/module-definition-6.0.0.tgz", + "integrity": "sha512-sEGP5nKEXU7fGSZUML/coJbrO+yQtxcppDAYWRE9ovWsTbFoUHB2qDUx564WUzDaBHXsD46JBbIK5WVTwCyu3w==", + "dev": true, + "dependencies": { + "ast-module-types": "^6.0.0", + "node-source-walk": "^7.0.0" + }, + "bin": { + "module-definition": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/module-lookup-amd": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/module-lookup-amd/-/module-lookup-amd-9.0.2.tgz", + "integrity": "sha512-p7PzSVEWiW9fHRX9oM+V4aV5B2nCVddVNv4DZ/JB6t9GsXY4E+ZVhPpnwUX7bbJyGeeVZqhS8q/JZ/H77IqPFA==", + "dev": true, + "dependencies": { + "commander": "^12.1.0", + "glob": "^7.2.3", + "requirejs": "^2.3.7", + "requirejs-config-file": "^4.0.0" + }, + "bin": { + "lookup-amd": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/module-lookup-amd/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true + }, + "node_modules/msgpackr": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz", + "integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==", + "dev": true, + "optional": true, + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "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/needle": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", + "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/ng-packagr": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-19.0.1.tgz", + "integrity": "sha512-PnXa/y3ce3v4bKJNtUBS7qcNoyv5g/tSthoMe23NyMV5kjNY4+hJT7h64zK+8tnJWTelCbIpoep7tmSPsOifBA==", + "dev": true, + "dependencies": { + "@rollup/plugin-json": "^6.1.0", + "@rollup/wasm-node": "^4.24.0", + "ajv": "^8.17.1", + "ansi-colors": "^4.1.3", + "browserslist": "^4.22.1", + "chokidar": "^4.0.1", + "commander": "^12.1.0", + "convert-source-map": "^2.0.0", + "dependency-graph": "^1.0.0", + "esbuild": "^0.24.0", + "fast-glob": "^3.3.2", + "find-cache-dir": "^3.3.2", + "injection-js": "^2.4.0", + "jsonc-parser": "^3.3.1", + "less": "^4.2.0", + "ora": "^5.1.0", + "piscina": "^4.7.0", + "postcss": "^8.4.47", + "rxjs": "^7.8.1", + "sass": "^1.79.5" + }, + "bin": { + "ng-packagr": "cli/main.js" + }, + "engines": { + "node": "^18.19.1 || >=20.11.1" + }, + "optionalDependencies": { + "rollup": "^4.24.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^19.0.0-next.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "tslib": "^2.3.0", + "typescript": ">=5.5 <5.7" + }, + "peerDependenciesMeta": { + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/ng-packagr/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ng-packagr/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/ng-packagr/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==", + "dev": true + }, + "node_modules/ng-packagr/node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/ng-packagr/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==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ng-packagr/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==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ng-packagr/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==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ng-packagr/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==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ng-packagr/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==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ng-packagr/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==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ng-packagr/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ng-packagr/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "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==", + "dev": true, + "optional": true + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.0.0.tgz", + "integrity": "sha512-zQS+9MTTeCMgY0F3cWPyJyRFAkVltQ1uXm+xXu/ES6KFgC6Czo1Seb9vQW2wNxSX2OrDTiqL0ojtkFxBQ0ypIw==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^14.0.3", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "tar": "^7.4.3", + "which": "^5.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-gyp/node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/node-gyp/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/node-gyp/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/node-gyp/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/nopt": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.0.0.tgz", + "integrity": "sha512-1L/fTJ4UmV/lUxT2Uf006pfZKTvAgCF+chz+0OgBHO8u2Z67pE7AaAUUj7CJy0lXqHmymUvGFt6NE9R3HER0yw==", + "dev": true, + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true + }, + "node_modules/node-source-walk": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-7.0.0.tgz", + "integrity": "sha512-1uiY543L+N7Og4yswvlm5NCKgPKDEXd9AUR9Jh3gen6oOeBsesr6LqhXom1er3eRzSUcVRWXzhv8tSNrIfGHKw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.24.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-package-data": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-7.0.0.tgz", + "integrity": "sha512-k6U0gKRIuNCTkwHGZqblCfLfBRh+w1vI6tBo+IeJwq2M8FUiOqhX7GH+GArQGScA7azd1WfyRCvxoXDO3hQDIA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^8.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-bundled": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-4.0.0.tgz", + "integrity": "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA==", + "dev": true, + "dependencies": { + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-install-checks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-7.1.1.tgz", + "integrity": "sha512-u6DCwbow5ynAX5BdiHQ9qvexme4U3qHW3MWe5NqH+NeBm0LbiH6zvGjNNew1fY+AZZUtVHbOPF3j7mJxbUzpXg==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", + "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-package-arg": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.0.tgz", + "integrity": "sha512-ZTE0hbwSdTNL+Stx2zxSqdu2KZfNDcrtrLdIk7XGnQFYBWYDho/ORvXtn5XEePcL3tFpGjHCV3X3xrtDh7eZ+A==", + "dev": true, + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-packlist": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-9.0.0.tgz", + "integrity": "sha512-8qSayfmHJQTx3nJWYbbUmflpyarbLMBc6LCAjYsiGtXxDB68HaZpb8re6zeaLGxZzDuMdhsg70jryJe+RrItVQ==", + "dev": true, + "dependencies": { + "ignore-walk": "^7.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-10.0.0.tgz", + "integrity": "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==", + "dev": true, + "dependencies": { + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-18.0.2.tgz", + "integrity": "sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ==", + "dev": true, + "dependencies": { + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opn": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", + "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "is-wsl": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/opn/node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ora/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==", + "dev": true + }, + "node_modules/ora/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ordered-binary": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.3.tgz", + "integrity": "sha512-oGFr3T+pYdTGJ+YFEILMpS3es+GiIbs9h/XQrclBXUtd44ey7XwfsMzM31f64I1SQOawDoDr/D823kNCADI8TA==", + "dev": true, + "optional": true + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", + "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, + "node_modules/pacote": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-20.0.0.tgz", + "integrity": "sha512-pRjC5UFwZCgx9kUFDVM9YEahv4guZ1nSLqwmWiLUnDbGsjs+U5w7z6Uc8HNR1a6x8qnu5y9xtGE6D1uAuYz+0A==", + "dev": true, + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "devOptional": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz", + "integrity": "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==", + "dev": true, + "dependencies": { + "entities": "^4.3.0", + "parse5": "^7.0.0", + "parse5-sax-parser": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-sax-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", + "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==", + "dev": true, + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "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==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/piscina": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.7.0.tgz", + "integrity": "sha512-b8hvkpp9zS0zsfa939b/jXbe64Z2gZv0Ha7FYPNUiDIB1y2AtxcOZdfP8xN8HFjUaqQiT9gRlfjAsoL8vdJ1Iw==", + "dev": true, + "optionalDependencies": { + "@napi-rs/nice": "^1.0.1" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dev": true, + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/portscanner": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.2.0.tgz", + "integrity": "sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "async": "^2.6.0", + "is-number-like": "^1.0.3" + }, + "engines": { + "node": ">=0.4", + "npm": ">=1.0.0" + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "dev": true, + "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.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-loader": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz", + "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==", + "dev": true, + "dependencies": { + "cosmiconfig": "^9.0.0", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/postcss-values-parser": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-6.0.2.tgz", + "integrity": "sha512-YLJpK0N1brcNJrs9WatuJFtHaV9q5aAOj+S4DI5S7jgHlRfm0PIbDCAFRYMQD5SHq7Fy6xsDhyutgS0QOAs0qw==", + "dev": true, + "dependencies": { + "color-name": "^1.1.4", + "is-url-superb": "^4.0.0", + "quote-unquote": "^1.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "postcss": "^8.2.9" + } + }, + "node_modules/postcss-values-parser/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==", + "dev": true + }, + "node_modules/precinct": { + "version": "12.1.2", + "resolved": "https://registry.npmjs.org/precinct/-/precinct-12.1.2.tgz", + "integrity": "sha512-x2qVN3oSOp3D05ihCd8XdkIPuEQsyte7PSxzLqiRgktu79S5Dr1I75/S+zAup8/0cwjoiJTQztE9h0/sWp9bJQ==", + "dev": true, + "dependencies": { + "@dependents/detective-less": "^5.0.0", + "commander": "^12.1.0", + "detective-amd": "^6.0.0", + "detective-cjs": "^6.0.0", + "detective-es6": "^5.0.0", + "detective-postcss": "^7.0.0", + "detective-sass": "^6.0.0", + "detective-scss": "^5.0.0", + "detective-stylus": "^5.0.0", + "detective-typescript": "^13.0.0", + "detective-vue2": "^2.0.3", + "module-definition": "^6.0.0", + "node-source-walk": "^7.0.0", + "postcss": "^8.4.40", + "typescript": "^5.5.4" + }, + "bin": { + "precinct": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/precinct/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/prettier": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", + "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-ms": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", + "dev": true, + "dependencies": { + "parse-ms": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-quick": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-4.0.0.tgz", + "integrity": "sha512-M+2MmeufXb/M7Xw3Afh1gxcYpj+sK0AxEfnfF958ktFeAyi5MsKY5brymVURQLgPLV1QaF5P4pb2oFJ54H3yzQ==", + "dev": true, + "dependencies": { + "execa": "^5.1.1", + "find-up": "^5.0.0", + "ignore": "^5.3.0", + "mri": "^1.2.0", + "picocolors": "^1.0.0", + "picomatch": "^3.0.1", + "tslib": "^2.6.2" + }, + "bin": { + "pretty-quick": "lib/cli.mjs" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "prettier": "^3.0.0" + } + }, + "node_modules/pretty-quick/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==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-quick/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==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-quick/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==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-quick/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==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-quick/node_modules/picomatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", + "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pretty-quick/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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, + "optional": true + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true, + "engines": { + "node": ">=0.9" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quote-unquote": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/quote-unquote/-/quote-unquote-1.0.0.tgz", + "integrity": "sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg==", + "dev": true + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/read-installed": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/read-installed/-/read-installed-4.0.3.tgz", + "integrity": "sha512-O03wg/IYuV/VtnK2h/KXEt9VIbMUFbk3ERG0Iu4FhLZw0EP0T9znqrYDGn6ncbEsXUFaUjiVAWXHzxwt3lhRPQ==", + "dev": true, + "dependencies": { + "debuglog": "^1.0.1", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "slide": "~1.1.3", + "util-extend": "^1.0.1" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.2" + } + }, + "node_modules/read-installed/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/read-installed/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-installed/node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true + }, + "node_modules/read-installed/node_modules/read-package-json": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.2.tgz", + "integrity": "sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA==", + "dev": true, + "dependencies": { + "glob": "^7.1.1", + "json-parse-even-better-errors": "^2.3.0", + "normalize-package-data": "^2.0.0", + "npm-normalize-package-bin": "^1.0.0" + } + }, + "node_modules/read-installed/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdir-scoped-modules": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", + "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "dependencies": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-parser": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", + "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==", + "dev": true + }, + "node_modules/regexpu-core": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dev": true, + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requirejs": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.7.tgz", + "integrity": "sha512-DouTG8T1WanGok6Qjg2SXuCMzszOo0eHeH9hDZ5Y4x8Je+9JB38HdTLT4/VA8OaUhBa0JPVHJ0pyBkM1z+pDsw==", + "dev": true, + "bin": { + "r_js": "bin/r.js", + "r.js": "bin/r.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/requirejs-config-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/requirejs-config-file/-/requirejs-config-file-4.0.0.tgz", + "integrity": "sha512-jnIre8cbWOyvr8a5F2KuqBnY+SDA4NXr/hzEZJG79Mxm2WiFQz2dzhC8ibtPJS7zkmBEl1mxSwp5HhC1W4qpxw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.0", + "stringify-object": "^3.2.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "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-dependency-path": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-dependency-path/-/resolve-dependency-path-4.0.0.tgz", + "integrity": "sha512-hlY1SybBGm5aYN3PC4rp15MzsJLM1w+MEA/4KU3UBPfz4S0lL3FL6mgv7JgaA8a+ZTeEQAiF1a1BuN2nkqiIlg==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/resolve-url-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", + "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", + "dev": true, + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/resolve-url-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resp-modifier": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/resp-modifier/-/resp-modifier-6.0.2.tgz", + "integrity": "sha512-U1+0kWC/+4ncRFYqQWTx/3qkfE6a4B/h3XXgmXypfa0SPZ3t7cbbaFk297PjQS/yov24R18h6OZe6iZwj3NSLw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "debug": "^2.2.0", + "minimatch": "^3.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/resp-modifier/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/resp-modifier/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true + }, + "node_modules/rimraf": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", + "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", + "dev": true, + "dependencies": { + "glob": "^11.0.0", + "package-json-from-dist": "^1.0.0" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/jackspeak": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", + "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/lru-cache": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", + "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", + "dev": true, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dev": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/roarr/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, + "node_modules/rollup": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.26.0.tgz", + "integrity": "sha512-ilcl12hnWonG8f+NxU6BlgysVA0gvY2l8N0R84S1HcINbW20bvwuCngJkkInV6LXhwRpucsW5k1ovDwEdBVrNg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.26.0", + "@rollup/rollup-android-arm64": "4.26.0", + "@rollup/rollup-darwin-arm64": "4.26.0", + "@rollup/rollup-darwin-x64": "4.26.0", + "@rollup/rollup-freebsd-arm64": "4.26.0", + "@rollup/rollup-freebsd-x64": "4.26.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.26.0", + "@rollup/rollup-linux-arm-musleabihf": "4.26.0", + "@rollup/rollup-linux-arm64-gnu": "4.26.0", + "@rollup/rollup-linux-arm64-musl": "4.26.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.26.0", + "@rollup/rollup-linux-riscv64-gnu": "4.26.0", + "@rollup/rollup-linux-s390x-gnu": "4.26.0", + "@rollup/rollup-linux-x64-gnu": "4.26.0", + "@rollup/rollup-linux-x64-musl": "4.26.0", + "@rollup/rollup-win32-arm64-msvc": "4.26.0", + "@rollup/rollup-win32-ia32-msvc": "4.26.0", + "@rollup/rollup-win32-x64-msvc": "4.26.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha512-CiaiuN6gapkdl+cZUr67W6I8jquN4lkak3vtIsIWCl4XIPP8ffsoyN6/+PuGXnQy8Cu8W2y9Xxh31Rq4M6wUug==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sass": { + "version": "1.80.7", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.7.tgz", + "integrity": "sha512-MVWvN0u5meytrSjsU7AWsbhoXi1sc58zADXFllfZzbsBT1GHjjar6JwBINYPRrkx/zqnQ6uqbQuHgE95O+C+eQ==", + "dev": true, + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass-loader": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.3.tgz", + "integrity": "sha512-gosNorT1RCkuCMyihv6FBRR7BMV06oKRAs+l4UMp1mlcVg9rWN6KMmUj3igjQwmYys4mDP3etEYJgiHRbgHCHA==", + "dev": true, + "dependencies": { + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/sass-lookup": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/sass-lookup/-/sass-lookup-6.0.1.tgz", + "integrity": "sha512-nl9Wxbj9RjEJA5SSV0hSDoU2zYGtE+ANaDS4OFUR7nYrquvBFvPKZZtQHe3lvnxCcylEDV00KUijjdMTUElcVQ==", + "dev": true, + "dependencies": { + "commander": "^12.0.0" + }, + "bin": { + "sass-lookup": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/sass-lookup/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sass/node_modules/immutable": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", + "dev": true + }, + "node_modules/sass/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "dev": true, + "optional": true + }, + "node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true + }, + "node_modules/send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/send/node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/send/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/send/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/send/node_modules/mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "mime": "cli.js" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/send/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/send/node_modules/statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/server-destroy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", + "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true + }, + "node_modules/sigstore": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-3.0.0.tgz", + "integrity": "sha512-PHMifhh3EN4loMcHCz6l3v/luzgT3za+9f8subGgeMNjbJjzH4Ij/YoX3Gvu+kaouJRIlVdTHHCREADYf+ZteA==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/sign": "^3.0.0", + "@sigstore/tuf": "^3.0.0", + "@sigstore/verify": "^2.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-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==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/snyk": { + "version": "1.1294.3", + "resolved": "https://registry.npmjs.org/snyk/-/snyk-1.1294.3.tgz", + "integrity": "sha512-ZF+F2bv293HmpFxZCV0x8hT3rQGOl6rPDoJq/TqBT1i5/nZypfn8v4A1Q4m6zUSUs1g6WJsS8QR5wTlR/eSvMQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@sentry/node": "^7.36.0", + "global-agent": "^3.0.0" + }, + "bin": { + "snyk": "bin/snyk" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/socket.io": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz", + "integrity": "sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.5.2", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "dev": true, + "dependencies": { + "ws": "~8.11.0" + } + }, + "node_modules/socket.io-client": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.5.tgz", + "integrity": "sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dev": true, + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sockjs/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "dev": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-5.0.0.tgz", + "integrity": "sha512-k2Dur7CbSLcAH73sBcIkV5xjPV4SzqO1NJ7+XaQl8if3VODDUj3FNchNGpqgJSKbvUfJuhVdv8K2Eu8/TNl2eA==", + "dev": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" + } + }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz", + "integrity": "sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.2", + "spdx-expression-parse": "^3.0.0", + "spdx-ranges": "^2.0.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", + "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==", + "dev": true + }, + "node_modules/spdx-ranges": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz", + "integrity": "sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==", + "dev": true + }, + "node_modules/spdx-satisfies": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/spdx-satisfies/-/spdx-satisfies-4.0.1.tgz", + "integrity": "sha512-WVzZ/cXAzoNmjCWiEluEA3BjHp5tiUmmhn9MK+X0tBbR9sOqtC6UQwmgCNrAIZvNlMuBUYAaHYfb2oqlF9SwKA==", + "dev": true, + "dependencies": { + "spdx-compare": "^1.0.0", + "spdx-expression-parse": "^3.0.0", + "spdx-ranges": "^2.0.0" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ssri": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz", + "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha512-wuTCPGlJONk/a1kqZ4fQM2+908lC7fa7nPYpTC1EhnvqLX/IICbeP1OZGDtA374trpSq68YubKUMo8oRhN46yg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-throttle": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz", + "integrity": "sha512-889+B9vN9dq7/vLbGyuHeZ6/ctf5sNuGWsDy89uNxkFTAgzy0eK7+w5fL3KLNRTkLle7EgZGvHUphZW0Q26MnQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "commander": "^2.2.0", + "limiter": "^1.0.5" + }, + "bin": { + "throttleproxy": "bin/throttleproxy.js" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/stream-throttle/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/stream-to-array": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz", + "integrity": "sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==", + "dev": true, + "dependencies": { + "any-promise": "^1.1.0" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", + "dev": true, + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/streamroller/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/streamroller/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "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==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylus-lookup": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/stylus-lookup/-/stylus-lookup-6.0.0.tgz", + "integrity": "sha512-RaWKxAvPnIXrdby+UWCr1WRfa+lrPMSJPySte4Q6a+rWyjeJyFOLJxr5GrAVfcMCsfVlCuzTAJ/ysYT8p8do7Q==", + "dev": true, + "dependencies": { + "commander": "^12.0.0" + }, + "bin": { + "stylus-lookup": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/stylus-lookup/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-observable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "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/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==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/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==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/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==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "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==", + "dev": true + }, + "node_modules/terser": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", + "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "dev": true, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tree-dump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", + "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/treeify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", + "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-graphviz": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/ts-graphviz/-/ts-graphviz-2.1.5.tgz", + "integrity": "sha512-IigMCo40QZvyyURRdYFh0DV6DGDt7OqkPM/TBGXSJKfNKnYmOfRg0tzSlnJS1TQCWFSTEtpBQsqmAZcziXJrWg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ts-graphviz" + } + ], + "dependencies": { + "@ts-graphviz/adapter": "^2.0.6", + "@ts-graphviz/ast": "^2.0.6", + "@ts-graphviz/common": "^2.1.5", + "@ts-graphviz/core": "^2.0.6" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/tuf-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-3.0.1.tgz", + "integrity": "sha512-+68OP1ZzSF84rTckf3FA95vJ1Zlx/uaXyiiKyPd1pA4rZNkpEvDAKmsu1xUSmbF/chCRYgZ6UZkDwC7PmzmAyA==", + "dev": true, + "dependencies": { + "@tufjs/models": "3.0.1", + "debug": "^4.3.6", + "make-fetch-happen": "^14.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/tuf-js/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/tuf-js/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-assert": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", + "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==", + "dev": true + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ua-parser-js": { + "version": "1.0.37", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", + "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "optional": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "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==", + "dev": true + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unique-filename": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz", + "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==", + "dev": true, + "dependencies": { + "unique-slug": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/unique-slug": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz", + "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "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.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.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==", + "dev": true + }, + "node_modules/util-extend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz", + "integrity": "sha512-mLs5zAK+ctllYBj+iAQvlDCwoxU/WDOUaJkcFudeiAX6OajC6BKXJUa9a+tbtkC11dz2Ufb7h0lyvIOVn4LADA==", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.0.tgz", + "integrity": "sha512-d7KLgL1LD3U3fgnvWEY1cQXoO/q6EQ1BSz48Sa149V/5zVTAbgmZIpyI8TRi6U9/JNyeYLlTKsEMPtLC27RFUg==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/vite": { + "version": "5.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.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": "*", + "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 + } + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "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" + } + }, + "node_modules/void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/walkdir": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", + "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true, + "optional": true + }, + "node_modules/webpack": { + "version": "5.96.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.96.1.tgz", + "integrity": "sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "dev": true, + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/webpack-dev-server": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.1.0.tgz", + "integrity": "sha512-aQpaN81X6tXie1FoOB7xlMfCsN19pSvRAeYUHOdFWOlhpQ/LlbfTqYwwmEDFV0h8GGuqmCmKmT+pxcUV/Nt2gQ==", + "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.19.2", + "graceful-fs": "^4.2.6", + "html-entities": "^2.4.0", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-subresource-integrity": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", + "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", + "dev": true, + "dependencies": { + "typed-assert": "^1.0.8" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", + "webpack": "^5.12.0" + }, + "peerDependenciesMeta": { + "html-webpack-plugin": { + "optional": true + } + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/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==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/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==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zone.js": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.0.tgz", + "integrity": "sha512-9oxn0IIjbCZkJ67L+LkhYWRyAy7axphb3VgE2MBDlOqnmHMPWGYMxJxBYFueFq/JGY2GMwS0rU+UCLunEmy5UA==" + } + } +} diff --git a/package.json b/package.json index 95ae6ceb..59152138 100644 --- a/package.json +++ b/package.json @@ -1,54 +1,100 @@ { - "name": "angular2-image-popup", - "version": "1.1.1", - "description": "Image popup directive for angular2", - "main": "index.js", - "dependencies": { - "@angular/common": "^2.1.0-beta.0", - "@angular/compiler": "^2.1.0-beta.0", - "@angular/core": "^2.1.0-beta.0", - "@angular/platform-browser": "^2.1.0-beta.0", - "@angular/platform-browser-dynamic": "^2.1.0-beta.0", - "@angular/upgrade": "^2.1.0-beta.0", - "core-js": "^2.4.0", - "font-awesome": "^4.6.3", - "reflect-metadata": "^0.1.3", - "rxjs": "5.0.0-beta.6", - "systemjs": "0.19.27", - "zone.js": "^0.6.12" - }, - "scripts": { - "start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ", - "tsc": "tsc", - "tsc:w": "tsc -w", - "lite": "lite-server", - "typings": "typings", - "postinstall": "typings install" - }, - "devDependencies": { - "concurrently": "^2.0.0", - "lite-server": "^2.2.0", - "typescript": "^2.0.0", - "typings": "^0.8.1" - }, + "name": "angular-modal-gallery", + "version": "13.0.0", + "description": "Image gallery for Angular", "license": "MIT", - "author": "Vimala A", - "keywords": [ - "angular2", - "angular2-image-popup", - "angular2-image", - "image-popup", - "popup", - "modal", - "angular2-modal-popup", - "modal-popup" - ], + "author": "Stefano Cappa", + "homepage": "https://github.com/Ks89", "repository": { "type": "git", - "url": "git+https://github.com/vimalavinisha/angular2-image-popup.git" + "url": "git+https://github.com/Ks89/angular-modal-gallery.git" }, - "bugs": { - "url": "https://github.com/vimalavinisha/angular2-image-popup/issues" + "engines": { + "node": ">=20.14.0", + "npm": ">=10.2.4" }, - "homepage": "https://github.com/vimalavinisha/angular2-image-popup#readme" + "scripts": { + "ng": "ng", + "start": "npm run serve", + "serve": "npm run serve:dev", + "serve:dev": "ng serve --configuration development", + "serve:prod": "ng serve --configuration production", + "build": "npm run build:lib && npm run build:main", + "build:lib": "npm run clean:dist && ng build @ks89/angular-modal-gallery --configuration production && npm run copy:build && npm run copy:other", + "build:lib:watch": "npm run clean:dist && ng build @ks89/angular-modal-gallery --configuration production --watch", + "build:main": "npm run build:main:dev", + "build:main:dev": "ng build --configuration development", + "build:main:prod": "ng build --configuration production", + "build:examples": "npm run build:lib && npm run clean:examples && npm run copy:dist:examples", + "build:all": "npm run build:lib && npm run build:main && npm run build:examples", + "clean": "npm run clean:main", + "clean:main": "npm run clean:dist && npm run clean:coverage", + "clean:dist": "rimraf @ks89 dist", + "clean:coverage": "rimraf coverage", + "clean:angular-cli-19": "rimraf examples/angular-cli-19/node_modules/@ks89 examples/angular-cli-19/dist", + "clean:angular-cli-material": "rimraf examples/angular-cli-material/node_modules/@ks89 examples/angular-cli-material/dist", + "clean:universal": "rimraf examples/universal/node_modules/@ks89 examples/universal/dist", + "clean:examples": "npm run clean:angular-cli-19 && npm run clean:angular-cli-material && npm run clean:universal", + "clean:all": "npm run clean:main && npm run clean:examples", + "copy:dist": "npm run copy:dist:examples", + "copy:dist:angular-cli-19": "cpr @ks89 examples/angular-cli-19/node_modules/@ks89 -o", + "copy:dist:angular-cli-material": "cpr @ks89 examples/angular-cli-material/node_modules/@ks89 -o", + "copy:dist:universal": "cpr @ks89 examples/universal/node_modules/@ks89 -o", + "copy:dist:examples": "npm run copy:dist:angular-cli-19 && npm run copy:dist:angular-cli-material && npm run copy:dist:universal", + "copy:build": "cpr dist/ks89/angular-modal-gallery @ks89/angular-modal-gallery -o", + "copy:other": "cpr README.md @ks89/angular-modal-gallery/README.md -o && cpr LICENSE @ks89/angular-modal-gallery/LICENSE -o && cpr CHANGELOG.md @ks89/angular-modal-gallery/CHANGELOG.md -o && cpr CONTRIBUTING.md @ks89/angular-modal-gallery/CONTRIBUTING.md -o", + "pretest": "npm run clean:coverage && npm run check:circulardeps", + "test": "ng test @ks89/angular-modal-gallery --watch=false", + "test:watch": "ng test @ks89/angular-modal-gallery --watch=true", + "check:licenses": "license-checker --exclude 'MIT, MIT OR X11, BSD, ISC, Apache-2.0'", + "check:circulardeps": "npx madge --circular --extensions ts ./", + "coveralls": "coveralls < coverage/ks89/angular-modal-gallery/lcov.info" + }, + "husky": { + "hooks": { + "pre-commit": "pretty-quick --staged --verbose" + } + }, + "private": true, + "dependencies": { + "@angular/cdk": "^19.0.4", + "@angular/common": "^19.0.5", + "@angular/compiler": "^19.0.5", + "@angular/core": "^19.0.5", + "@angular/forms": "^19.0.5", + "@angular/platform-browser": "^19.0.5", + "@angular/platform-browser-dynamic": "^19.0.5", + "@angular/router": "^19.0.5", + "@fortawesome/fontawesome-svg-core": "^6.7.2", + "@fortawesome/free-solid-svg-icons": "^6.7.2", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^19.0.6", + "@angular/cli": "~19.0.6", + "@angular/compiler-cli": "^19.0.5", + "@types/jasmine": "~5.1.0", + "@types/node": "^20.12.13", + "coveralls": "^3.1.1", + "cpr": "^3.0.1", + "cross-env": "^7.0.0", + "husky": "^9.1.7", + "jasmine-core": "~5.4.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "karma-mocha-reporter": "^2.2.5", + "license-checker": "^25.0.1", + "madge": "^8.0.0", + "ng-packagr": "^19.0.1", + "prettier": "^3.4.2", + "pretty-quick": "^4.0.0", + "rimraf": "^6.0.1", + "snyk": "^1.1294.3", + "typescript": "~5.6.3" + } } diff --git a/projects/ks89/angular-modal-gallery/karma.conf.js b/projects/ks89/angular-modal-gallery/karma.conf.js new file mode 100644 index 00000000..43e70b6b --- /dev/null +++ b/projects/ks89/angular-modal-gallery/karma.conf.js @@ -0,0 +1,101 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa (Ks89) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage'), + require('karma-mocha-reporter'), + require('@angular-devkit/build-angular/plugins/karma') + ], + client: { + jasmine: { + // you can add configuration options for Jasmine here + // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html + // for example, you can disable the random execution with `random: false` + // or set a specific seed with `seed: 4321` + }, + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + jasmineHtmlReporter: { + suppressAll: true // removes the duplicated traces + }, + coverageReporter: { + dir: require('path').join(__dirname, '../../../coverage/ks89/angular-modal-gallery'), + subdir: '.', + reporters: [ + // To use coveralls and other tools I need lcov coverage. + // I can use lcovonly to get the right file, however I also want the html output. + // type: 'lcov' contains both outputs 'html' and 'lcovonly'!!! + // { type: 'html' }, + { type: 'lcov' }, + { type: 'text-summary' } + ], + // check: { + // global: { + // statements: 80, + // branches: 80, + // functions: 80, + // lines: 80 + // } + // }, + // watermarks: { + // statements: [ 50, 75 ], + // functions: [ 50, 75 ], + // branches: [ 50, 75 ], + // lines: [ 50, 75 ] + // } + }, + reporters: ['mocha'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['ChromeHeadless'], + singleRun: false, + restartOnFileChange: false, + + customLaunchers: { + ChromeHeadless: { + base: 'Chrome', + flags: [ + '--no-sandbox', + // See https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md + '--headless', + '--disable-gpu', + // Without a remote debugging port, Google Chrome exits immediately. + ' --remote-debugging-port=9222' + ] + } + } + }); +}; diff --git a/projects/ks89/angular-modal-gallery/ng-package.json b/projects/ks89/angular-modal-gallery/ng-package.json new file mode 100644 index 00000000..8a466a12 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/ng-package.json @@ -0,0 +1,7 @@ +{ + "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", + "dest": "../../../dist/ks89/angular-modal-gallery", + "lib": { + "entryFile": "src/public-api.ts" + } +} diff --git a/projects/ks89/angular-modal-gallery/package.json b/projects/ks89/angular-modal-gallery/package.json new file mode 100644 index 00000000..7fda8c5b --- /dev/null +++ b/projects/ks89/angular-modal-gallery/package.json @@ -0,0 +1,55 @@ +{ + "name": "@ks89/angular-modal-gallery", + "version": "13.0.0", + "description": "Image gallery for Angular", + "license": "MIT", + "author": "Stefano Cappa", + "engines": { + "node": ">=20.0.0", + "npm": ">=10.0.0" + }, + "homepage": "https://ks89.github.io/angular-modal-gallery-2024-v13.github.io/", + "dependencies": { + "tslib": ">=2.3.0" + }, + "peerDependencies": { + "@angular/platform-browser": ">=19.0.0", + "@angular/common": ">=19.0.0", + "@angular/core": ">=19.0.0", + "@angular/cdk": ">=19.0.0", + "rxjs": ">=7.8.0" + }, + "keywords": [ + "angular-modal-gallery", + "ngx-gallery", + "angular2-gallery", + "angular2-modal-gallery", + "angular2-modal", + "angular-gallery", + "modal-gallery", + "angular-modal", + "ngx-modal-gallery", + "popup", + "plain", + "plain-gallery", + "gallery", + "carousel", + "modal", + "material", + "material-design", + "angular2-modal-popup", + "angular-modal-popup", + "modal-popup", + "swipe", + "gesture", + "touch", + "mobile" + ], + "repository": { + "type": "git", + "url": "https://github.com/Ks89/angular-modal-gallery.git" + }, + "bugs": { + "url": "https://github.com/Ks89/angular-modal-gallery/issues" + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/accessibility-default.ts b/projects/ks89/angular-modal-gallery/src/lib/components/accessibility-default.ts new file mode 100644 index 00000000..867dd22e --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/accessibility-default.ts @@ -0,0 +1,49 @@ +import { AccessibilityConfig } from '../model/accessibility.interface'; + +/** + * Default accessibility configuration. + */ +export const KS_DEFAULT_ACCESSIBILITY_CONFIG: AccessibilityConfig = { + backgroundAriaLabel: 'Modal gallery full screen background', + backgroundTitle: '', + + plainGalleryContentAriaLabel: 'Plain gallery content', + plainGalleryContentTitle: '', + + modalGalleryContentAriaLabel: 'Modal gallery content', + modalGalleryContentTitle: '', + + loadingSpinnerAriaLabel: 'The current image is loading. Please be patient.', + loadingSpinnerTitle: 'The current image is loading. Please be patient.', + + mainContainerAriaLabel: 'Current image and navigation', + mainContainerTitle: '', + mainPrevImageAriaLabel: 'Previous image', + mainPrevImageTitle: 'Previous image', + mainNextImageAriaLabel: 'Next image', + mainNextImageTitle: 'Next image', + + dotsContainerAriaLabel: 'Image navigation dots', + dotsContainerTitle: '', + dotAriaLabel: 'Navigate to image number', + + previewsContainerAriaLabel: 'Image previews', + previewsContainerTitle: '', + previewScrollPrevAriaLabel: 'Scroll previous previews', + previewScrollPrevTitle: 'Scroll previous previews', + previewScrollNextAriaLabel: 'Scroll next previews', + previewScrollNextTitle: 'Scroll next previews', + + carouselContainerAriaLabel: 'Current image and navigation', + carouselContainerTitle: '', + carouselPrevImageAriaLabel: 'Previous image', + carouselPrevImageTitle: 'Previous image', + carouselNextImageAriaLabel: 'Next image', + carouselNextImageTitle: 'Next image', + carouselPreviewsContainerAriaLabel: 'Image previews', + carouselPreviewsContainerTitle: '', + carouselPreviewScrollPrevAriaLabel: 'Scroll previous previews', + carouselPreviewScrollPrevTitle: 'Scroll previous previews', + carouselPreviewScrollNextAriaLabel: 'Scroll next previews', + carouselPreviewScrollNextTitle: 'Scroll next previews' +}; diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/accessible.component.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/components/accessible.component.spec.ts new file mode 100644 index 00000000..5db7d7c6 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/accessible.component.spec.ts @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2017-2024 Stefano Cappa (Ks89) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AccessibleComponent } from './accessible.component'; +import { + DIRECTION_LEFT, + DIRECTION_RIGHT, + ENTER_CODE, + ENTER_KEY, + MOUSE_MAIN_BUTTON_CLICK, + NEXT, + NOTHING, + PREV, + SPACE_CODE, + SPACE_KEY +} from '../utils/user-input.util'; + +let comp: AccessibleComponent; +let fixture: ComponentFixture; + +function initTestBed(): void { + TestBed.configureTestingModule({ + declarations: [AccessibleComponent] + }); +} + +describe('AccessibleComponent', () => { + beforeEach(() => { + initTestBed(); + fixture = TestBed.createComponent(AccessibleComponent); + comp = fixture.componentInstance; + }); + + it('should instantiate it', () => expect(comp).not.toBeNull()); + + describe('---Keyboard navigation---', () => { + it('should handle navigation event with direction right and space key', () => { + const keyboardEvent: KeyboardEvent = new KeyboardEvent('keydown', { + code: SPACE_CODE, + key: SPACE_KEY + }); + const result: number = comp.handleNavigationEvent(DIRECTION_RIGHT, keyboardEvent); + expect(result).toBe(NEXT); + }); + it('should handle navigation event with direction right and enter key', () => { + const keyboardEvent: KeyboardEvent = new KeyboardEvent('keydown', { + code: ENTER_CODE, + key: ENTER_KEY + }); + const result: number = comp.handleNavigationEvent(DIRECTION_RIGHT, keyboardEvent); + expect(result).toBe(NEXT); + }); + + it('should handle navigation event with direction left and space key', () => { + const keyboardEvent: KeyboardEvent = new KeyboardEvent('keydown', { + code: SPACE_CODE, + key: SPACE_KEY + }); + const result: number = comp.handleNavigationEvent(DIRECTION_LEFT, keyboardEvent); + expect(result).toBe(PREV); + }); + it('should handle navigation event with direction left and enter key', () => { + const keyboardEvent: KeyboardEvent = new KeyboardEvent('keydown', { + code: ENTER_CODE, + key: ENTER_KEY + }); + const result: number = comp.handleNavigationEvent(DIRECTION_LEFT, keyboardEvent); + expect(result).toBe(PREV); + }); + + it('should handle navigation event with direction right and an invalid key', () => { + const keyboardEvent: KeyboardEvent = new KeyboardEvent('keydown', { + code: '', // invalid code and key + key: '' + }); + const result: number = comp.handleNavigationEvent(DIRECTION_RIGHT, keyboardEvent); + expect(result).toBe(NOTHING); + }); + + it('should handle navigation event with direction left and an invalid key', () => { + const keyboardEvent: KeyboardEvent = new KeyboardEvent('keydown', { + code: '', // invalid code and key + key: '' + }); + const result: number = comp.handleNavigationEvent(DIRECTION_LEFT, keyboardEvent); + expect(result).toBe(NOTHING); + }); + + // it('should handle navigation event without event', () => { + // const result: number = comp.handleNavigationEvent(DIRECTION_LEFT, undefined); + // expect(result).toBe(NOTHING); + // }); + }); + + describe('---Mouse navigation---', () => { + it('should handle navigation event with direction right and space key', () => { + const mouseEvent: MouseEvent = new MouseEvent('click', { + button: MOUSE_MAIN_BUTTON_CLICK + }); + const result: number = comp.handleNavigationEvent(DIRECTION_RIGHT, mouseEvent); + expect(result).toBe(NEXT); + }); + + it('should handle navigation event with direction left and space key', () => { + const mouseEvent: MouseEvent = new MouseEvent('click', { + button: MOUSE_MAIN_BUTTON_CLICK + }); + const result: number = comp.handleNavigationEvent(DIRECTION_LEFT, mouseEvent); + expect(result).toBe(PREV); + }); + + it('should handle navigation event with direction right and an invalid key', () => { + const mouseEvent: MouseEvent = new MouseEvent('click', { + button: -2 // invalid button + }); + const result: number = comp.handleNavigationEvent(DIRECTION_RIGHT, mouseEvent); + expect(result).toBe(NOTHING); + }); + it('should handle navigation event with direction LEFT and an invalid key', () => { + const mouseEvent: MouseEvent = new MouseEvent('click', { + button: -2 // invalid button + }); + const result: number = comp.handleNavigationEvent(DIRECTION_LEFT, mouseEvent); + expect(result).toBe(NOTHING); + }); + }); + + // describe('---Unknown navigation---', () => { + // it(`should handle navigation event, but since it's not permitted, the result should be NOTHING`, () => { + // const unrecognizedEvent: FocusEvent = new FocusEvent('click', { + // relatedTarget: null + // }); + // const result: number = comp.handleNavigationEvent(DIRECTION_LEFT, unrecognizedEvent); + // expect(result).toBe(NOTHING); + // }); + // }); + + describe('---Keyboard image event---', () => { + it('should handle keyboard image event with space key', () => { + const keyboardEvent: KeyboardEvent = new KeyboardEvent('keydown', { + code: SPACE_CODE, + key: SPACE_KEY + }); + const result: number = comp.handleImageEvent(keyboardEvent); + expect(result).toBe(NEXT); + }); + it('should handle keyboard image event with enter key', () => { + const keyboardEvent: KeyboardEvent = new KeyboardEvent('keydown', { + code: ENTER_CODE, + key: ENTER_KEY + }); + const result: number = comp.handleImageEvent(keyboardEvent); + expect(result).toBe(NEXT); + }); + it('should handle keyboard image event with an invalid key', () => { + const keyboardEvent: KeyboardEvent = new KeyboardEvent('keydown', { + code: '', // invalid code and key + key: '' + }); + const result: number = comp.handleImageEvent(keyboardEvent); + expect(result).toBe(NOTHING); + }); + }); + + describe('---Mouse image event---', () => { + it('should handle mouse image event with space key', () => { + const mouseEvent: MouseEvent = new MouseEvent('click', { + button: MOUSE_MAIN_BUTTON_CLICK + }); + const result: number = comp.handleImageEvent(mouseEvent); + expect(result).toBe(NEXT); + }); + it('should handle mouse image event with enter key', () => { + const mouseEvent: MouseEvent = new MouseEvent('click', { + button: MOUSE_MAIN_BUTTON_CLICK + }); + const result: number = comp.handleImageEvent(mouseEvent); + expect(result).toBe(NEXT); + }); + it('should handle mouse image event with an invalid key', () => { + const mouseEvent: MouseEvent = new MouseEvent('click', { + button: -2 // invalid button + }); + const result: number = comp.handleImageEvent(mouseEvent); + expect(result).toBe(NOTHING); + }); + }); + + describe('---Unknown image event---', () => { + it(`should handle image event, but since it's not permitted, the result should be NOTHING`, () => { + // tslint:disable-next-line:no-any + const unrecognizedEvent: any = new FocusEvent('click', { + relatedTarget: null + }); + const result: number = comp.handleImageEvent(unrecognizedEvent); + expect(result).toBe(NOTHING); + }); + }); + + // describe('---Undefined image event---', () => { + // it(`should handle image event, but since it's undefined, the result should be NOTHING`, () => { + // const result: number = comp.handleImageEvent(undefined); + // expect(result).toBe(NOTHING); + // }); + // }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/accessible.component.ts b/projects/ks89/angular-modal-gallery/src/lib/components/accessible.component.ts new file mode 100644 index 00000000..a6cd325d --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/accessible.component.ts @@ -0,0 +1,131 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { ChangeDetectionStrategy, Component } from '@angular/core'; + +import { DIRECTION_RIGHT, MOUSE_MAIN_BUTTON_CLICK, NEXT, NOTHING, PREV, ENTER_CODE, SPACE_CODE } from '../utils/user-input.util'; + +/** + * Provides some useful methods to add accessibility features to subclasses. + * In particular, it exposes a method to handle navigation event with both Keyboard and Mouse + * and another with also the direction (right or left). + */ +@Component({ + selector: 'ks-accessible', + template: ``, + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: false +}) +export class AccessibleComponent { + constructor() {} + + /** + * Method to handle navigation events with both Keyboard and Mouse. + * @param string direction of the navigation that can be either 'next' or 'prev' + * @param KeyboardEvent | MouseEvent event payload + * @returns number -1 for PREV, 1 for NEXT and 0 for NOTHING + */ + handleNavigationEvent(direction: string, event: KeyboardEvent | MouseEvent): number { + if (!event) { + return NOTHING; + } + if (event instanceof KeyboardEvent) { + return this.handleKeyboardNavigationEvent(direction, event); + } else if (event instanceof MouseEvent) { + return this.handleMouseNavigationEvent(direction, event); + } + return NOTHING; + } + + /** + * Method to handle events over an image, for instance a keypress with the Keyboard or a Mouse click. + * @param event KeyboardEvent | MouseEvent payload + * @returns number 1 for NEXT and 0 for NOTHING + */ + handleImageEvent(event: KeyboardEvent | MouseEvent): number { + if (!event) { + return NOTHING; + } + if (event instanceof KeyboardEvent) { + return this.handleImageKeyboardEvent(event); + } else if (event instanceof MouseEvent) { + return this.handleImageMouseEvent(event); + } + return NOTHING; + } + + /** + * Private method to handle keyboard events over an image. + * @param event KeyboardEvent payload + * @returns number 1 for NEXT and 0 for NOTHING + */ + private handleImageKeyboardEvent(event: KeyboardEvent): number { + const key: string = event.code; + if (key === SPACE_CODE || key === ENTER_CODE) { + return NEXT; + } + return NOTHING; + } + + /** + * Private method to handle mouse events over an image. + * @param MouseEvent event payload + * @returns number 1 for NEXT and 0 for NOTHING + */ + private handleImageMouseEvent(event: MouseEvent): number { + const mouseBtn: number = event.button; + if (mouseBtn === MOUSE_MAIN_BUTTON_CLICK) { + return NEXT; + } + return NOTHING; + } + + /** + * Method to handle events over an image, for instance a keypress with the Keyboard or a Mouse click. + * @param string direction of the navigation that can be either 'next' or 'prev' + * @param KeyboardEvent event payload + * @returns number -1 for PREV, 1 for NEXT and 0 for NOTHING + */ + private handleKeyboardNavigationEvent(direction: string, event: KeyboardEvent): number { + const key: string = event.code; + if (key === SPACE_CODE || key === ENTER_CODE) { + return direction === DIRECTION_RIGHT ? NEXT : PREV; + } + return NOTHING; + } + + /** + * Method to handle events over an image, for instance a keypress with the Keyboard or a Mouse click. + * @param string direction of the navigation that can be either 'next' or 'prev' + * @param MouseEvent event payload + * @returns number -1 for PREV, 1 for NEXT and 0 for NOTHING + */ + private handleMouseNavigationEvent(direction: string, event: MouseEvent): number { + const mouseBtn: number = event.button; + if (mouseBtn === MOUSE_MAIN_BUTTON_CLICK) { + return direction === DIRECTION_RIGHT ? NEXT : PREV; + } + return NOTHING; + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel-previews/carousel-previews.component.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel-previews/carousel-previews.component.spec.ts new file mode 100644 index 00000000..18a9e3d2 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel-previews/carousel-previews.component.spec.ts @@ -0,0 +1,807 @@ +/* + * Copyright (C) 2017-2021 Stefano Cappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentFixture, fakeAsync, flush, TestBed, tick } from '@angular/core/testing'; +import { DebugElement, SimpleChanges } from '@angular/core'; +import { By, SafeResourceUrl } from '@angular/platform-browser'; +import { CarouselPreviewsComponent } from './carousel-previews.component'; +import { SizeDirective } from '../../../directives/size.directive'; +import { KS_DEFAULT_ACCESSIBILITY_CONFIG } from '../../accessibility-default'; +import { InternalLibImage } from '../../../model/image-internal.class'; +import { AccessibilityConfig } from '../../../model/accessibility.interface'; +import { Image, ImageEvent, ModalImage, PlainImage } from '../../../model/image.class'; +import { CarouselConfig } from '../../../model/carousel-config.interface'; +import { BreakpointsConfig, CarouselPreviewConfig } from '../../../model/carousel-preview-config.interface'; +import { Action } from '../../../model/action.enum'; +import { BreakpointObserver } from '@angular/cdk/layout'; +import { MediumMockedBreakpointObserver } from '../../../utils/breakpoint-observer-mock.spec'; +import { ConfigService } from '../../../services/config.service'; +import { FallbackImageDirective } from '../../../directives/fallback-image.directive'; + +let comp: CarouselPreviewsComponent; +let fixture: ComponentFixture; + +interface NavigationTestData { + initial: { + start: number, + end: number, + activeIndex: number + }; + expected: { + start: number, + end: number, + activeIndex: number + }; +} + +const CUSTOM_ACCESSIBILITY: AccessibilityConfig = Object.assign({}, KS_DEFAULT_ACCESSIBILITY_CONFIG); +CUSTOM_ACCESSIBILITY.previewsContainerAriaLabel = 'custom previewsContainerAriaLabel'; +CUSTOM_ACCESSIBILITY.previewsContainerTitle = 'custom previewsContainerTitle'; +CUSTOM_ACCESSIBILITY.previewScrollNextAriaLabel = 'custom previewScrollNextAriaLabel'; +CUSTOM_ACCESSIBILITY.previewScrollNextTitle = 'custom previewScrollNextTitle'; +CUSTOM_ACCESSIBILITY.previewScrollPrevAriaLabel = 'custom previewScrollPrevAriaLabel'; +CUSTOM_ACCESSIBILITY.previewScrollPrevTitle = 'custom previewScrollPrevTitle'; + +const DEFAULT_WIDTH = '25%'; +const DEFAULT_HEIGHT = '150px'; +const CUSTOM_PREVIEW_HEIGHTS: string[] = ['200px', '150px', '300px']; + +const GALLERY_ID = 1; + +const IMAGES: InternalLibImage[] = [ + new InternalLibImage( + 0, + { + img: '/assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1' + }, + { + img: '/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', + title: 'First image title', + alt: 'First image alt', + ariaLabel: 'First image aria-label' + } + ), + new InternalLibImage(1, {img: '/assets/images/gallery/pexels-photo-47223.jpeg'}, {img: '/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg'}), + new InternalLibImage( + 2, + { + img: '/assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3', + title: 'Third image title', + alt: 'Third image alt', + ariaLabel: 'Third image aria-label' + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new InternalLibImage( + 3, + { + img: '/assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4', + title: 'Fourth image title (modal obj)', + alt: 'Fourth image alt (modal obj)', + ariaLabel: 'Fourth image aria-label (modal obj)' + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', + title: 'Fourth image title (plain obj)', + alt: 'Fourth image alt (plain obj)', + ariaLabel: 'Fourth image aria-label (plain obj)' + } + ), + new InternalLibImage(4, {img: '/assets/images/gallery/pexels-photo-93750.jpeg'}, {img: '/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg'}), + new InternalLibImage( + 5, + { + img: '/assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6' + }, + {img: '/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg'} + ), + new InternalLibImage(6, {img: '/assets/images/gallery/pexels-photo-96947.jpeg'}, {img: '/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg'}) +]; + +const NAVIGATION_NEXT_PREVIEWS: NavigationTestData[] = [ + { + initial: {start: 0, end: 4, activeIndex: 0}, + expected: {start: 1, end: 5, activeIndex: 2} + }, + { + initial: {start: 0, end: 4, activeIndex: 0}, + expected: {start: 0, end: 4, activeIndex: 0} + }, + { + initial: {start: 0, end: 4, activeIndex: 0}, + expected: {start: 0, end: 4, activeIndex: 1} + }, + { + initial: {start: 0, end: 4, activeIndex: 0}, + expected: {start: 1, end: 5, activeIndex: 3} + } +]; + +const NAVIGATION_PREV_PREVIEWS: NavigationTestData[] = [ + { + initial: {start: 3, end: 7, activeIndex: 6}, + expected: {start: 2, end: 6, activeIndex: 4} + }, + { + initial: {start: 3, end: 7, activeIndex: 6}, + expected: {start: 3, end: 7, activeIndex: 6} + }, + { + initial: {start: 3, end: 7, activeIndex: 6}, + expected: {start: 3, end: 7, activeIndex: 5} + }, + { + initial: {start: 3, end: 7, activeIndex: 6}, + expected: {start: 2, end: 6, activeIndex: 3} + } +]; + +function checkArrows(arrows: DebugElement[], first: boolean, last: boolean, + accessibility: AccessibilityConfig = KS_DEFAULT_ACCESSIBILITY_CONFIG): void { + const prevArrowClass = first ? 'empty-arrow-preview-image' : 'left-arrow-preview-image'; + const nextArrowClass = last ? 'empty-arrow-preview-image' : 'right-arrow-preview-image'; + expect(arrows.length).toBe(2); + expect(arrows[0].attributes.class).toBe('nav-left'); + expect(arrows[0].attributes.role).toBe('button'); + expect(arrows[0].attributes['aria-label']).toBe(accessibility.carouselPreviewScrollPrevAriaLabel); + expect(arrows[0].properties.tabIndex).toBe(first ? -1 : 0); // because with the first image, prev arrow is hidden + expect(arrows[0].children[0].attributes['aria-hidden']).toBe('true'); + expect(arrows[0].children[0].properties.title).toBe(accessibility.carouselPreviewScrollPrevTitle); + expect(containsClasses(arrows[0].children[0].properties.className, prevArrowClass + ' inside')).toBeTrue(); + expect(arrows[1].attributes.class).toBe('nav-right'); + expect(arrows[1].attributes.role).toBe('button'); + expect(arrows[1].attributes['aria-label']).toBe(accessibility.carouselPreviewScrollNextAriaLabel); + expect(arrows[1].properties.tabIndex).toBe(last ? -1 : 0); + expect(arrows[1].children[0].attributes['aria-hidden']).toBe('true'); + expect(arrows[1].children[0].properties.title).toBe(accessibility.carouselPreviewScrollNextTitle); + expect(containsClasses(arrows[1].children[0].properties.className, nextArrowClass + ' inside')).toBeTrue(); +} + +function containsClasses(actualClasses: string, expectedClasses: string): boolean { + const actual: string[] = actualClasses.split(' '); + const expected: string[] = expectedClasses.split(' '); + let count = 0; + if (actual.length !== expected.length) { + return false; + } + expected.forEach((item: string) => { + if (actual.includes(item)) { + count++; + } + }); + return count === expected.length; +} + +function getAriaLabel(preview: Image): string { + if (!preview.plain) { + return preview.modal.ariaLabel || ''; + } + return preview.plain.ariaLabel || preview.modal.ariaLabel || ''; +} + +function getTitle(preview: Image): string { + if (!preview.plain) { + return preview.modal.title || ''; + } + return preview.plain.title || preview.modal.title || ''; +} + +function getAlt(preview: Image): string { + if (!preview.plain) { + return preview.modal.alt || ''; + } + return preview.plain.alt || preview.modal.alt || ''; +} + +function checkPreview(previewElement: DebugElement, previewImage: InternalLibImage, isActive: boolean, width: string = DEFAULT_WIDTH, height: string = DEFAULT_HEIGHT): void { + const currentPlainImg: PlainImage | undefined = previewImage.plain; + const currentModalImg: ModalImage = previewImage.modal; + expect(previewElement.name).toBe('img'); + expect(previewElement.attributes.role).toBe('img'); + expect(previewElement.attributes['aria-label']).toBe(getAriaLabel(previewImage)); + expect(previewElement.styles.width).toBe(width); + // FIXME why is not working? + // expect(previewElement.styles.height).toBe(height); + expect(containsClasses(previewElement.properties.className, 'inside preview-image' + (isActive ? ' active' : ''))).toBeTrue(); + expect(previewElement.properties.src).toBe(currentPlainImg && currentPlainImg.img ? currentPlainImg.img : currentModalImg.img); + expect(previewElement.properties.title).toBe(getTitle(previewImage)); + expect(previewElement.properties.alt).toBe(getAlt(previewImage)); + expect(previewElement.properties.tabIndex).toBe(0); +} + +function initTestBed(): void { + TestBed.configureTestingModule({ + declarations: [CarouselPreviewsComponent, SizeDirective, FallbackImageDirective] + }).overrideComponent(CarouselPreviewsComponent, { + set: { + providers: [ + { + // by default inject a mocked BreakpointObserver service with Medium size by default + provide: BreakpointObserver, + useClass: MediumMockedBreakpointObserver + }, + { + provide: ConfigService, + useClass: ConfigService + } + ] + } + }); +} + +const CAROUSEL_CONFIG_DEFAULT: CarouselConfig = { + maxWidth: '100%', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false +} as CarouselConfig; + +const DEFAULT_BREAKPOINTS: BreakpointsConfig = {xSmall: 100, small: 100, medium: 150, large: 200, xLarge: 200}; +const DEFAULT_PREVIEW_CONFIG: CarouselPreviewConfig = { + visible: true, + number: 4, + arrows: true, + clickable: true, + width: 100 / 4 + '%', + maxHeight: '200px', + breakpoints: DEFAULT_BREAKPOINTS +}; + +describe('CarouselPreviewsComponent', () => { + beforeEach(() => { + initTestBed(); + fixture = TestBed.createComponent(CarouselPreviewsComponent); + comp = fixture.componentInstance; + }); + + it('should instantiate it', () => expect(comp).not.toBeNull()); + + describe('---YES---', () => { + + it(`should display previews (first one is active) based of input images`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + carouselPreviewsConfig: DEFAULT_PREVIEW_CONFIG, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + carouselConfig: CAROUSEL_CONFIG_DEFAULT + }); + const initialActiveImage = 0; + const numOfPreviews: number = DEFAULT_PREVIEW_CONFIG.number as number; + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[initialActiveImage]; + comp.images = IMAGES; + fixture.detectChanges(); + + expect(comp.start).toBe(initialActiveImage); + expect(comp.end).toBe(numOfPreviews); + expect(comp.previews).toEqual(IMAGES.slice(initialActiveImage, numOfPreviews)); + + const element: DebugElement = fixture.debugElement; + + const arrows: DebugElement[] = element.queryAll(By.css('a')); + checkArrows(arrows, true, false); + + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + + const previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + + const previewImages: InternalLibImage[] = IMAGES.slice(initialActiveImage, numOfPreviews); + previews.forEach((preview: DebugElement, i: number) => { + checkPreview(preview, previewImages[i], i === initialActiveImage, DEFAULT_WIDTH, DEFAULT_HEIGHT); + }); + }); + + NAVIGATION_NEXT_PREVIEWS.forEach((val: NavigationTestData, index: number) => { + it(`should display previews and navigate next clicking on images. Test i=${index}`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + carouselPreviewsConfig: DEFAULT_PREVIEW_CONFIG, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + carouselConfig: CAROUSEL_CONFIG_DEFAULT + }); + const initialActiveImage = val.initial.activeIndex; // initial active preview + const newActiveImage = val.expected.activeIndex; // preview to click => so the next active preview after the click action + const numOfPreviews: number = DEFAULT_PREVIEW_CONFIG.number as number; + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[initialActiveImage]; + comp.images = IMAGES; + fixture.detectChanges(); + + expect(comp.start).toBe(val.initial.start); + expect(comp.end).toBe(val.initial.end); + expect(comp.previews).toEqual(IMAGES.slice(val.initial.start, val.initial.end)); + + spyOn(comp, 'onImageEvent').and.callThrough(); + + const element: DebugElement = fixture.debugElement; + + let previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + + let arrows: DebugElement[] = element.queryAll(By.css('a')); + checkArrows(arrows, comp.start === 0, comp.end === IMAGES.length); + + let previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + + let previewImages: InternalLibImage[] = IMAGES.slice(val.initial.start, val.initial.end); + previews.forEach((preview: DebugElement, i: number) => { + checkPreview(preview, previewImages[i], i === val.initial.activeIndex - val.initial.start, DEFAULT_WIDTH, DEFAULT_HEIGHT); + }); + + comp.clickPreview.subscribe((e: ImageEvent) => { + // check click event payload + expect(e.action).toBe(Action.CLICK); + expect(e.result).toBe(val.expected.activeIndex); + + // it's required to change the currentImage, + // because this operation is done by its parent GalleryComponent + comp.currentImage = IMAGES[newActiveImage]; + + comp.ngOnChanges({ + currentImage: { + previousValue: IMAGES[initialActiveImage], + currentValue: IMAGES[newActiveImage], + firstChange: true, + isFirstChange: () => true + }, + images: { + previousValue: IMAGES, + currentValue: IMAGES, + firstChange: false, + isFirstChange: () => false + } + } as SimpleChanges); + + fixture.detectChanges(); + expect(comp.onImageEvent).toHaveBeenCalled(); + + previewImages = IMAGES.slice(val.expected.start, val.expected.end); + + expect(comp.start).toBe(val.expected.start); + expect(comp.end).toBe(val.expected.end); + expect(comp.previews).toEqual(previewImages); + + arrows = element.queryAll(By.css('a')); + checkArrows(arrows, comp.start === 0, comp.end === IMAGES.length); + + previewsContainer = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + + previews = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + + previews.forEach((preview: DebugElement, i: number) => { + checkPreview(preview, previewImages[i], i === val.expected.activeIndex - val.expected.start, DEFAULT_WIDTH, DEFAULT_HEIGHT); + }); + }); + + previews[newActiveImage].nativeElement.click(); + }); + }); + + NAVIGATION_PREV_PREVIEWS.forEach((val: NavigationTestData, index: number) => { + it(`should display previews and navigate prev clicking on images. Test i=${index}`, fakeAsync(() => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + carouselPreviewsConfig: DEFAULT_PREVIEW_CONFIG, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + carouselConfig: CAROUSEL_CONFIG_DEFAULT + }); + const initialActiveImage = val.initial.activeIndex; // initial active preview + const newActiveImage = val.expected.activeIndex; // preview to click => so the next active preview after the click action + const numOfPreviews: number = DEFAULT_PREVIEW_CONFIG.number as number; + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[initialActiveImage]; + comp.images = IMAGES; + fixture.detectChanges(); + const element: DebugElement = fixture.debugElement; + let arrows: DebugElement[] = element.queryAll(By.css('a')); + // first I have to go to the end of previews to be able to navigate back to the beginning as specified by the NAVIGATION_PREV_PREVIEWS item + arrows[1].nativeElement.click(); + tick(10); + flush(); + fixture.detectChanges(); + arrows[1].nativeElement.click(); + tick(10); + flush(); + fixture.detectChanges(); + arrows[1].nativeElement.click(); + tick(10); + flush(); + fixture.detectChanges(); + // check if I'm really at the end + expect(comp.start).toBe(val.initial.start); + expect(comp.end).toBe(val.initial.end); + expect(comp.previews).toEqual(IMAGES.slice(val.initial.start, val.initial.end)); + let previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + arrows = element.queryAll(By.css('a')); + checkArrows(arrows, comp.start === 0, comp.end === IMAGES.length); + let previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + let previewImages: InternalLibImage[] = IMAGES.slice(val.initial.start, val.initial.end); + previews.forEach((preview: DebugElement, i: number) => { + checkPreview(preview, previewImages[i], i === val.initial.activeIndex - val.initial.start, DEFAULT_WIDTH, DEFAULT_HEIGHT); + }); + + spyOn(comp, 'onImageEvent').and.callThrough(); + + comp.clickPreview.subscribe((e: ImageEvent) => { + // check click event payload + expect(e.action).toBe(Action.CLICK); + expect(e.result).toBe(val.expected.activeIndex); + + // it's required to change the currentImage, + // because this operation is done by its parent GalleryComponent + comp.currentImage = IMAGES[newActiveImage]; + + comp.ngOnChanges({ + currentImage: { + previousValue: IMAGES[initialActiveImage], + currentValue: IMAGES[newActiveImage], + firstChange: true, + isFirstChange: () => true + }, + images: { + previousValue: IMAGES, + currentValue: IMAGES, + firstChange: false, + isFirstChange: () => false + } + } as SimpleChanges); + + fixture.detectChanges(); + expect(comp.onImageEvent).toHaveBeenCalled(); + + previewImages = IMAGES.slice(val.expected.start, val.expected.end); + + expect(comp.start).toBe(val.expected.start); + expect(comp.end).toBe(val.expected.end); + expect(comp.previews).toEqual(previewImages); + + arrows = element.queryAll(By.css('a')); + checkArrows(arrows, comp.start === 0, comp.end === IMAGES.length); + + previewsContainer = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + + previews = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + + previews.forEach((preview: DebugElement, i: number) => { + checkPreview(preview, previewImages[i], i === val.expected.activeIndex - val.expected.start, DEFAULT_WIDTH, DEFAULT_HEIGHT); + }); + }); + + previews[newActiveImage - val.initial.start].nativeElement.click(); + })); + }); + + it(`should display previews and navigate clicking on arrow 'next'`, fakeAsync(() => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + carouselPreviewsConfig: DEFAULT_PREVIEW_CONFIG, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + carouselConfig: CAROUSEL_CONFIG_DEFAULT + }); + const initialActiveImage = 0; // initial active preview + const numOfPreviews: number = DEFAULT_PREVIEW_CONFIG.number as number; + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[initialActiveImage]; + comp.images = IMAGES; + fixture.detectChanges(); + + expect(comp.start).toBe(initialActiveImage); + expect(comp.end).toBe(numOfPreviews); + expect(comp.previews).toEqual(IMAGES.slice(initialActiveImage, numOfPreviews)); + + spyOn(comp, 'onNavigationEvent').and.callThrough(); + const element: DebugElement = fixture.debugElement; + + // check initial state + let previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + let arrows: DebugElement[] = element.queryAll(By.css('a')); + checkArrows(arrows, comp.start === 0, comp.end === IMAGES.length); + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + let previewImages: InternalLibImage[] = IMAGES.slice(initialActiveImage, numOfPreviews); + previews.forEach((preview: DebugElement, i: number) => checkPreview(preview, previewImages[i], i === 0, DEFAULT_WIDTH, DEFAULT_HEIGHT)); + + // click on right arrow to navigate next + [{start: 1, end: 5}, {start: 2, end: 6}, {start: 3, end: 7}].forEach((val: { start: number, end: number }) => { + arrows[1].nativeElement.click(); + tick(10); + flush(); + fixture.detectChanges(); + comp.currentImage = IMAGES[initialActiveImage]; // current image must be the initial image, because I'm navigating previews without changing the current image + previewImages = IMAGES.slice(val.start, val.end); + expect(comp.start).toBe(val.start); + expect(comp.end).toBe(val.end); + expect(comp.previews).toEqual(IMAGES.slice(val.start, val.end)); + arrows = element.queryAll(By.css('a')); + checkArrows(arrows, comp.start === 0, comp.end === IMAGES.length); + previews = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + previews.forEach((preview: DebugElement, i: number) => checkPreview(preview, previewImages[i], false, DEFAULT_WIDTH, DEFAULT_HEIGHT)); + }); + })); + + it(`should display previews with custom accessibility`, () => { + const IMAGES_CUSTOM_ACCESSIBILITY: InternalLibImage[] = [...IMAGES].map((image: InternalLibImage) => { + const newImage: InternalLibImage = Object.assign({}, image); + newImage.modal.title = 'custom accessibility title'; + newImage.modal.alt = 'custom accessibility alt'; + newImage.modal.ariaLabel = 'custom accessibility ariaLabel'; + if (newImage.plain) { + newImage.plain.title = 'custom accessibility title'; + newImage.plain.alt = 'custom accessibility alt'; + newImage.plain.ariaLabel = 'custom accessibility ariaLabel'; + } + return newImage; + }); + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + carouselPreviewsConfig: DEFAULT_PREVIEW_CONFIG, + accessibilityConfig: CUSTOM_ACCESSIBILITY, + carouselConfig: CAROUSEL_CONFIG_DEFAULT + }); + const numOfPreviews = 4; + const initialActiveImage = 0; + comp.id = GALLERY_ID; + comp.currentImage = IMAGES_CUSTOM_ACCESSIBILITY[initialActiveImage]; + comp.images = IMAGES_CUSTOM_ACCESSIBILITY; + fixture.detectChanges(); + + const previewImages: InternalLibImage[] = IMAGES_CUSTOM_ACCESSIBILITY.slice(initialActiveImage, numOfPreviews); + + expect(comp.start).toBe(initialActiveImage); + expect(comp.end).toBe(DEFAULT_PREVIEW_CONFIG.number as number); + expect(comp.previews).toEqual(previewImages); + + const element: DebugElement = fixture.debugElement; + + const arrows: DebugElement[] = element.queryAll(By.css('a')); + expect(arrows.length).toBe(2); + checkArrows(arrows, true, false, CUSTOM_ACCESSIBILITY); + + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(CUSTOM_ACCESSIBILITY.carouselPreviewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(CUSTOM_ACCESSIBILITY.carouselPreviewsContainerTitle); + + const previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + // DEFAULT_HEIGHT because forces by breakpoints when browser is small (like in test) + previews.forEach((preview: DebugElement, i: number) => checkPreview(preview, previewImages[i], i === 0, DEFAULT_WIDTH, DEFAULT_HEIGHT)); + }); + + it(`should display a custom number of previews without hidden navigation arrows`, () => { + const numOfPreviews = 5; + const CUSTOM_WIDTH = 100 / numOfPreviews + '%'; + const customPreviewConfigFive: CarouselPreviewConfig = { + visible: true, + number: numOfPreviews, + arrows: false, + clickable: true, + width: CUSTOM_WIDTH, + maxHeight: '200px', // however, if browser is small (like in test), this will be smaller + breakpoints: DEFAULT_BREAKPOINTS + }; + const initialActiveImage = 0; + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + carouselPreviewsConfig: customPreviewConfigFive, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + carouselConfig: CAROUSEL_CONFIG_DEFAULT + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[initialActiveImage]; + comp.images = IMAGES; + fixture.detectChanges(); + + const previewImages: InternalLibImage[] = IMAGES.slice(initialActiveImage, numOfPreviews); + + expect(comp.start).toBe(initialActiveImage); + expect(comp.end).toBe(customPreviewConfigFive.number as number); + expect(comp.previews).toEqual(previewImages); + + const element: DebugElement = fixture.debugElement; + + const arrows: DebugElement[] = element.queryAll(By.css('a')); + expect(arrows.length).toBe(2); + // use true, true because both arrows are hidden + checkArrows(arrows, true, true); + + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.carouselPreviewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.carouselPreviewsContainerTitle); + + const previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + // DEFAULT_HEIGHT because forces by breakpoints when browser is small (like in test) + previews.forEach((preview: DebugElement, i: number) => checkPreview(preview, previewImages[i], i === 0, CUSTOM_WIDTH, DEFAULT_HEIGHT)); + }); + + CUSTOM_PREVIEW_HEIGHTS.forEach((height: string, index: number) => { + it(`should display previews with custom sizes. Index i=${index}`, () => { + const initialActiveImage = 0; + // create a custom preview config based on the default one, but with different maxHeight + const CUSTOM_PREVIEW_CONFIG: CarouselPreviewConfig = Object.assign({}, DEFAULT_PREVIEW_CONFIG, {maxHeight: height}); + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + carouselPreviewsConfig: CUSTOM_PREVIEW_CONFIG, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + carouselConfig: CAROUSEL_CONFIG_DEFAULT + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[initialActiveImage]; + comp.images = IMAGES; + fixture.detectChanges(); + + const previewImages: InternalLibImage[] = IMAGES.slice(initialActiveImage, CUSTOM_PREVIEW_CONFIG.number); + + expect(comp.start).toBe(initialActiveImage); + expect(comp.end).toBe(CUSTOM_PREVIEW_CONFIG.number as number); + expect(comp.previews).toEqual(previewImages); + + const element: DebugElement = fixture.debugElement; + + const arrows: DebugElement[] = element.queryAll(By.css('a')); + expect(arrows.length).toBe(2); + checkArrows(arrows, true, false); + + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + + const previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(CUSTOM_PREVIEW_CONFIG.number as number); + // DEFAULT_HEIGHT because forces by breakpoints when browser is small (like in test) + previews.forEach((preview: DebugElement, i: number) => checkPreview(preview, previewImages[i], i === 0, DEFAULT_WIDTH, DEFAULT_HEIGHT)); + }); + }); + + // TODO not working. But it isn't an issue of this test, instead it's something related to the library, because + // TODO I should implement keyboard navigation on the previews-container and not on single previews + // it(`should display previews (first one is active) and go to the second one with keyboard's right arrow`, fakeAsync(() => { + // const initialActiveImage = 0; + // comp.previewConfig = DEFAULT_PREVIEW_CONFIG; + // comp.accessibilityConfig = KS_DEFAULT_ACCESSIBILITY_CONFIG; + // comp.currentImage = IMAGES[initialActiveImage]; + // comp.carouselConfig = CAROUSEL_CONFIG_DEFAULT; + // comp.images = IMAGES; + // fixture.detectChanges(); + // + // spyOn(comp, 'onImageEvent').and.callThrough(); + // + // const previewImages: InternalLibImage[] = IMAGES.slice(initialActiveImage, DEFAULT_PREVIEW_CONFIG.number); + // + // expect(comp.start).toBe(initialActiveImage); + // expect(comp.end).toBe(DEFAULT_PREVIEW_CONFIG.number); + // expect(comp.previews).toEqual(previewImages); + // + // const element: DebugElement = fixture.debugElement; + // + // const arrows: DebugElement[] = element.queryAll(By.css('a')); + // expect(arrows.length).toBe(2); + // checkArrows(arrows, true, false); + // + // const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + // expect(previewsContainer.name).toBe('nav'); + // expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + // expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + // + // const previews: DebugElement[] = element.queryAll(By.css('img')); + // expect(previews.length).toBe(DEFAULT_PREVIEW_CONFIG.number); + // // DEFAULT_HEIGHT because forces by breakpoints when browser is small (like in test) + // previews.forEach((preview: DebugElement, i: number) => checkPreview(preview, previewImages[i], i === 0, DEFAULT_WIDTH, DEFAULT_HEIGHT)); + // + // previews[initialActiveImage + 1].nativeElement.focus(); + // previews[initialActiveImage + 1].triggerEventHandler('keyup', {keyCode: RIGHT_ARROW_KEYCODE}); + // tick(100); + // flush(); + // fixture.detectChanges(); + // expect(comp.start).toBe(initialActiveImage + 1); + // expect(comp.end).toBe(DEFAULT_PREVIEW_CONFIG.number + 1); + // expect(comp.previews).toEqual(previewImages); + // })); + + [-2, -1, 0].forEach((numberOfPreviews: number, index: number) => { + it(`should display previews with number <= 0, so it will be forced to the default value. Test i=${index}`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + carouselPreviewsConfig: DEFAULT_PREVIEW_CONFIG, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + carouselConfig: CAROUSEL_CONFIG_DEFAULT + }); + const initialActiveImage = 0; + const numOfPreviews = 4; + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[initialActiveImage]; + comp.images = IMAGES; + fixture.detectChanges(); + + expect(comp.start).toBe(initialActiveImage); + expect(comp.end).toBe(numOfPreviews); + expect(comp.previews).toEqual(IMAGES.slice(initialActiveImage, numOfPreviews)); + + const element: DebugElement = fixture.debugElement; + const arrows: DebugElement[] = element.queryAll(By.css('a')); + checkArrows(arrows, true, false); + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + const previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + }); + }); + }); + + describe('---NO---', () => { + it(`shouldn't display previews because visibility is false`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + carouselPreviewsConfig: {visible: false} as CarouselPreviewConfig, // hide previews + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + carouselConfig: CAROUSEL_CONFIG_DEFAULT + }); + const initialActiveImage = 0; + const numOfPreviews: number = DEFAULT_PREVIEW_CONFIG.number as number; + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[initialActiveImage]; + comp.images = IMAGES; + fixture.detectChanges(); + + expect(comp.start).toBe(initialActiveImage); + expect(comp.end).toBe(numOfPreviews); + expect(comp.previews).toEqual(IMAGES.slice(initialActiveImage, numOfPreviews)); + + const element: DebugElement = fixture.debugElement; + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer).toBeNull(); + const previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(0); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel-previews/carousel-previews.component.ts b/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel-previews/carousel-previews.component.ts new file mode 100644 index 00000000..ada05169 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel-previews/carousel-previews.component.ts @@ -0,0 +1,536 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + EventEmitter, + HostBinding, + Input, + OnChanges, + OnDestroy, + OnInit, + Output, + SimpleChange, + SimpleChanges +} from '@angular/core'; +import { DomSanitizer, SafeResourceUrl, SafeStyle } from '@angular/platform-browser'; +import { BreakpointObserver, Breakpoints, BreakpointState } from '@angular/cdk/layout'; + +import { Subscription } from 'rxjs'; + +import { AccessibleComponent } from '../../accessible.component'; + +import { AccessibilityConfig } from '../../../model/accessibility.interface'; +import { Image, ImageEvent } from '../../../model/image.class'; +import { InternalLibImage } from '../../../model/image-internal.class'; +import { CarouselPreviewConfig } from '../../../model/carousel-preview-config.interface'; +import { CarouselConfig } from '../../../model/carousel-config.interface'; + +import { NEXT, PREV } from '../../../utils/user-input.util'; +import { getIndex } from '../../../utils/image.util'; +import { Action } from '../../../model/action.enum'; +import { ConfigService } from '../../../services/config.service'; +import { LibConfig } from '../../../model/lib-config.interface'; + +/** + * Default max height of previews. + */ +const DEFAULT_MAX_HEIGHT = '200px'; + +/** + * Component with image previews for carousel + */ +@Component({ + selector: 'ks-carousel-previews', + styleUrls: ['carousel-previews.scss', '../../previews-arrows.scss'], + templateUrl: 'carousel-previews.html', + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: false +}) +export class CarouselPreviewsComponent extends AccessibleComponent implements OnInit, OnChanges, OnDestroy { + /** + * Variable to change the max-width of the host component + */ + @HostBinding('style.max-width') + hostMaxWidth = '100%'; + + /** + * Variable to set aria-label of the host component + */ + @HostBinding('attr.aria-label') + ariaLabel = `Carousel previews`; + + /** + * TODO write doc + */ + @Input() + id!: number; + /** + * Object of type `InternalLibImage` that represent the visible image. + */ + @Input() + currentImage!: InternalLibImage; + /** + * Array of `InternalLibImage` that represent the model of this library with all images, + * thumbs and so on. + */ + @Input() + images!: InternalLibImage[]; + + /** + * Output to emit the clicked preview. The payload contains the `InternalLibImage` associated to the clicked preview. + */ + @Output() + clickPreview: EventEmitter = new EventEmitter(); + + /** + * Object of type `CarouselConfig` to init CarouselComponent's features. + * For instance, it contains parameters to change the style, how it navigates and so on. + */ + carouselConfig: CarouselConfig | undefined; + /** + * Object of type `CarouselPreviewConfig` to init PreviewsComponent's features. + * For instance, it contains a param to show/hide this component, sizes. + */ + previewConfig: CarouselPreviewConfig | undefined; + /** + * Object of type `AccessibilityConfig` to init custom accessibility features. + * For instance, it contains titles, alt texts, aria-labels and so on. + */ + accessibilityConfig: AccessibilityConfig | undefined; + /** + * Enum of type `Action` that represents a mouse click on a button. + * Declared here to be used inside the template. + */ + clickAction: Action = Action.CLICK; + /** + * Enum of type `Action` that represents a keyboard action. + * Declared here to be used inside the template. + */ + keyboardAction: Action = Action.KEYBOARD; + /** + * Array of `InternalLibImage` exposed to the template. This field is initialized + * applying transformations, default values and so on to the input of the same type. + */ + previews: InternalLibImage[] = []; + /** + * Variable with the preview's maxHeight + */ + previewMaxHeight: string = DEFAULT_MAX_HEIGHT; + /** + * Start index (inclusive) of the input images used to display previews. + */ + // @ts-ignore + start: number; + /** + * End index (non inclusive) of the input images used to display previews. + */ + // @ts-ignore + end: number; + + private readonly breakpointSubscription: Subscription; + + constructor( + private ref: ChangeDetectorRef, + private breakpointObserver: BreakpointObserver, + // sanitizer is used only to sanitize style before add it to background property when legacyIE11Mode is enabled + private sanitizer: DomSanitizer, + private configService: ConfigService + ) { + super(); + + // listen for width changes and update preview heights accordingly + this.breakpointSubscription = breakpointObserver + .observe([Breakpoints.XSmall, Breakpoints.Small, Breakpoints.Medium, Breakpoints.Large, Breakpoints.XLarge]) + .subscribe((result: BreakpointState) => { + if (!this.previewConfig || !this.previewConfig.breakpoints) { + return; + } + if (result.breakpoints[Breakpoints.XSmall]) { + this.updateHeight(this.previewConfig.breakpoints.xSmall); + } else if (result.breakpoints[Breakpoints.Small]) { + this.updateHeight(this.previewConfig.breakpoints.small); + } else if (result.breakpoints[Breakpoints.Medium]) { + this.updateHeight(this.previewConfig.breakpoints.medium); + } else if (result.breakpoints[Breakpoints.Large]) { + this.updateHeight(this.previewConfig.breakpoints.large); + } else if (result.breakpoints[Breakpoints.XLarge]) { + this.updateHeight(this.previewConfig.breakpoints.xLarge); + } + }); + } + + /** + * Method to update the height of previews, passing the desired height as input. + * @param configBreakpointHeight is a number that represent the desired height to set. + */ + private updateHeight(configBreakpointHeight: number): void { + if (this.previewConfig && this.previewConfig.maxHeight) { + const heightNum: number = +this.previewConfig.maxHeight.replace('/px/g', '').replace('/%/g', ''); + this.previewMaxHeight = Math.min(configBreakpointHeight, heightNum) + 'px'; + } else { + const heightNum: number = +DEFAULT_MAX_HEIGHT.replace('/px/g', '').replace('/%/g', ''); + this.previewMaxHeight = Math.min(configBreakpointHeight, heightNum) + 'px'; + } + this.ref.markForCheck(); + } + + /** + * Method ´ngOnInit´ to build `configPreview` applying a default value and also to + * init the `previews` array. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called only one time!!! + */ + ngOnInit(): void { + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + this.carouselConfig = libConfig.carouselConfig; + this.previewConfig = libConfig.carouselPreviewsConfig; + this.accessibilityConfig = libConfig.accessibilityConfig; + + if (!this.previewConfig || !this.previewConfig.maxHeight || !this.previewConfig.breakpoints) { + throw new Error('Internal library error - previewConfig must be defined'); + } + // change the max-width of this component if there is a specified width !== 100% in carouselConfig + if (this.carouselConfig && this.carouselConfig.maxWidth !== '100%') { + this.hostMaxWidth = this.carouselConfig.maxWidth; + } + + this.previewMaxHeight = this.previewConfig.maxHeight; + // init previews based on currentImage and the full array of images + this.initPreviews(this.currentImage, this.images); + + // apply custom height based on responsive breakpoints + // This is required, because the breakpointSubscription is not triggered at creation, + // but only when the width changes + const isXsmallScreen = this.breakpointObserver.isMatched(Breakpoints.XSmall); + const isSmallScreen = this.breakpointObserver.isMatched(Breakpoints.Small); + const isMediumScreen = this.breakpointObserver.isMatched(Breakpoints.Medium); + const isLargeScreen = this.breakpointObserver.isMatched(Breakpoints.Large); + const isxLargeScreen = this.breakpointObserver.isMatched(Breakpoints.XLarge); + if (isXsmallScreen) { + this.updateHeight(this.previewConfig.breakpoints.xSmall); + } else if (isSmallScreen) { + this.updateHeight(this.previewConfig.breakpoints.small); + } else if (isMediumScreen) { + this.updateHeight(this.previewConfig.breakpoints.medium); + } else if (isLargeScreen) { + this.updateHeight(this.previewConfig.breakpoints.large); + } else if (isxLargeScreen) { + this.updateHeight(this.previewConfig.breakpoints.xLarge); + } + } + + /** + * Method to check if an image is active (i.e. a preview image). + * @param InternalLibImage preview is an image to check if it's active or not + * @returns boolean true if is active, false otherwise + */ + isActive(preview: InternalLibImage): boolean { + if (!preview || !this.currentImage) { + return false; + } + return preview.id === this.currentImage.id; + } + + /** + * Method ´ngOnChanges´ to update `previews` array. + * Also, both `start` and `end` local variables will be updated accordingly. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called when any data-bound property of a directive changes!!! + */ + ngOnChanges(changes: SimpleChanges): void { + const simpleChange: SimpleChange = changes.currentImage; + if (!simpleChange) { + return; + } + + const prev: InternalLibImage = simpleChange.previousValue; + const current: InternalLibImage = simpleChange.currentValue; + + if (current && changes.images && changes.images.previousValue && changes.images.currentValue) { + // I'm in this if statement, if input images are changed (for instance, because I removed one of them with the 'delete button', + // or because users changed the images array while modal gallery is still open). + // In this case, I have to re-init previews, because the input array of images is changed. + this.initPreviews(current, changes.images.currentValue); + } + + if (prev && current && prev.id !== current.id) { + // to manage infinite sliding I have to reset both `start` and `end` at the beginning + // to show again previews from the first image. + // This happens when you navigate over the last image to return to the first one + let prevIndex: number; + let currentIndex: number; + try { + prevIndex = getIndex(prev, this.images); + currentIndex = getIndex(current, this.images); + } catch (err) { + console.error('Cannot get previous and current image indexes in previews'); + throw err; + } + + // apply a formula to get a values to be used to decide if go next, return back or stay without doing anything + const calc = Math.floor((this.end - this.start) / 2) + this.start; + + if (prevIndex === this.images.length - 1 && currentIndex === 0) { + // first image + this.setBeginningIndexesPreviews(); + this.previews = this.images.filter((img: InternalLibImage, i: number) => i >= this.start && i < this.end); + return; + } + // the same for the opposite case, when you navigate back from the fist image to go to the last one. + if (prevIndex === 0 && currentIndex === this.images.length - 1) { + // last image + this.setEndIndexesPreviews(); + this.previews = this.images.filter((img: InternalLibImage, i: number) => i >= this.start && i < this.end); + return; + } + + if (this.previewConfig && (this.previewConfig.number as number) % 2 === 0) { + if (calc > currentIndex) { + this.previous(); + } else { + this.next(); + } + } else { + if (calc > currentIndex) { + this.previous(); + } + if (calc < currentIndex) { + this.next(); + } + } + } + } + + /** + * Method called by events from both keyboard and mouse on a preview. + * This will trigger the `clickpreview` output with the input preview as its payload. + * @param InternalLibImage preview that triggered this method + * @param KeyboardEvent | MouseEvent event payload + * @param Action that triggered this event (Action.NORMAL by default) + */ + onImageEvent(preview: InternalLibImage, event: KeyboardEvent | MouseEvent, action: Action = Action.NORMAL): void { + if (!this.previewConfig || !this.previewConfig.clickable) { + return; + } + const clickedImageIndex: number = this.images.indexOf(preview); + const result: number = super.handleImageEvent(event); + if (result === NEXT) { + this.clickPreview.emit({ action, result: clickedImageIndex } as ImageEvent); + } else if (result === PREV) { + this.clickPreview.emit({ action, result: clickedImageIndex } as ImageEvent); + } + } + + /** + * Method called by events from both keyboard and mouse on a navigation arrow. + * @param string direction of the navigation that can be either 'next' or 'prev' + * @param KeyboardEvent | MouseEvent event payload + */ + onNavigationEvent(direction: string, event: KeyboardEvent | MouseEvent): void { + const result: number = super.handleNavigationEvent(direction, event); + if (result === NEXT) { + this.next(); + } else if (result === PREV) { + this.previous(); + } + } + + /** + * Method to get aria-label text for a preview image. + * @param Image is the preview + */ + getAriaLabel(preview: Image): string { + if (!preview.plain) { + return preview.modal.ariaLabel || ''; + } + return preview.plain.ariaLabel || preview.modal.ariaLabel || ''; + } + + /** + * Method to get title text for a preview image. + * @param Image is the preview + */ + getTitle(preview: Image): string { + if (!preview.plain) { + return preview.modal.title || ''; + } + return preview.plain.title || preview.modal.title || ''; + } + + /** + * Method to get alt text for a preview image. + * @param Image is the preview + */ + getAlt(preview: Image): string { + if (!preview.plain) { + return preview.modal.alt || ''; + } + return preview.plain.alt || preview.modal.alt || ''; + } + + /** + * Method used in the template to track ids in ngFor. + * @param number index of the array + * @param Image item of the array + * @returns number the id of the item + */ + trackById(index: number, item: Image): number { + return item.id; + } + + /** + * Method used in template to sanitize an url when you need legacyIE11Mode. + * In this way you can set an url as background of a div. + * @param unsafeStyle is a string or a SafeResourceUrl that represents the url to sanitize. + * @param unsafeStyleFallback is a string or a SafeResourceUrl that represents the fallback url to sanitize. + * @returns a SafeStyle object that can be used in template without problems. + */ + sanitizeUrlBgStyle(unsafeStyle: string | SafeResourceUrl, unsafeStyleFallback: string | SafeResourceUrl): SafeStyle { + // Method used only to sanitize background-image style before add it to background property when legacyIE11Mode is enabled + let bg: string = 'url(' + unsafeStyle + ')'; + if (!!unsafeStyleFallback) { + // if a fallback image is defined, append it. In this way, it will be used by the browser as fallback. + bg += ', ' + 'url(' + unsafeStyleFallback + ')'; + } + return this.sanitizer.bypassSecurityTrustStyle(bg); + } + + /** + * Method to cleanup resources. In fact, it cleans breakpointSubscription. + * This is an angular lifecycle hook that is called when this component is destroyed. + */ + ngOnDestroy(): void { + if (this.breakpointSubscription) { + this.breakpointSubscription.unsubscribe(); + } + } + + /** + * Private method to init previews based on the currentImage and the full array of images. + * The current image in mandatory to show always the current preview (as highlighted). + * @param InternalLibImage currentImage to decide how to show previews, because I always want to see the current image as highlighted + * @param InternalLibImage[] images is the array of all images. + */ + private initPreviews(currentImage: InternalLibImage, images: InternalLibImage[]): void { + let index: number; + try { + index = getIndex(currentImage, images); + } catch (err) { + throw err; + } + switch (index) { + case 0: + // first image + this.setBeginningIndexesPreviews(); + break; + case images.length - 1: + // last image + this.setEndIndexesPreviews(); + break; + // default: + // // other images + // // TODO unused because it starts always at image 0 + // this.setIndexesPreviews(); + // break; + } + this.previews = images.filter((img: InternalLibImage, i: number) => i >= this.start && i < this.end); + } + + /** + * Private method to init both `start` and `end` to the beginning. + */ + private setBeginningIndexesPreviews(): void { + if (!this.previewConfig || this.previewConfig.number === undefined) { + throw new Error('Internal library error - previewConfig and number must be defined'); + } + + this.start = 0; + this.end = Math.min(this.previewConfig.number as number, this.images.length); + } + + /** + * Private method to init both `start` and `end` to the end. + */ + private setEndIndexesPreviews(): void { + if (!this.previewConfig || this.previewConfig.number === undefined) { + throw new Error('Internal library error - previewConfig and number must be defined'); + } + + this.start = this.images.length - 1 - ((this.previewConfig.number as number) - 1); + this.end = this.images.length; + } + + /** + * Private method to update the visible previews navigating to the right (next). + */ + private next(): void { + // check if nextImage should be blocked + if (this.isPreventSliding(this.images.length - 1)) { + return; + } + + if (this.end === this.images.length) { + return; + } + + this.start++; + this.end = Math.min(this.end + 1, this.images.length); + + this.previews = this.images.filter((img: InternalLibImage, i: number) => i >= this.start && i < this.end); + } + + /** + * Private method to update the visible previews navigating to the left (previous). + */ + private previous(): void { + // check if prevImage should be blocked + if (this.isPreventSliding(0)) { + return; + } + + if (this.start === 0) { + return; + } + + this.start = Math.max(this.start - 1, 0); + this.end = Math.min(this.end - 1, this.images.length); + + this.previews = this.images.filter((img: InternalLibImage, i: number) => i >= this.start && i < this.end); + } + + /** + * Private method to block/permit sliding between previews. + * @param number boundaryIndex is the first or the last index of `images` input array + * @returns boolean if true block sliding, otherwise not + */ + private isPreventSliding(boundaryIndex: number): boolean { + return getIndex(this.currentImage, this.images) === boundaryIndex; + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel-previews/carousel-previews.html b/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel-previews/carousel-previews.html new file mode 100644 index 00000000..753a41fc --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel-previews/carousel-previews.html @@ -0,0 +1,42 @@ + diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel-previews/carousel-previews.scss b/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel-previews/carousel-previews.scss new file mode 100644 index 00000000..89cfdef9 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel-previews/carousel-previews.scss @@ -0,0 +1,103 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// all svgs are converted to base 64 with this website http://b64.io/ + +$container-margin-bottom: 0; +$preview-image-top-margin: 3px; +$preview-image-bottom-margin: 3px; +$preview-container-fade-in-time: .8s; + +$nav-color: #919191; +$nav-animation-time: 1s; +$nav-transition-time: .5s; +$nav-side-margin: 10px; + +:host { + position: relative; + margin-top: $preview-image-top-margin; + margin-bottom: $preview-image-bottom-margin; + // default width + width: 100%; +} + +.previews-container { + align-items: center; + animation: fadein-semi-visible08 $preview-container-fade-in-time; + display: flex; + flex-direction: row; + justify-content: center; + margin-bottom: $container-margin-bottom; + + > .preview-inner-container { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + flex-wrap: nowrap; + // default width + width: 100%; + + > .preview-image { + cursor: pointer; + object-fit: cover; + + &.unclickable { + cursor: not-allowed; + } + } + } + + .nav { + position: absolute; + top: calc(50% - 7px); + color: $nav-color; + z-index: 1000; + //animation: animatezoom $nav-animation-time; + cursor: pointer; + transition: all $nav-transition-time; + + &:hover { + transform: scale(1.1); + } + } + + > .nav-left { + @extend .nav; + margin-right: $nav-side-margin; + left: 10px; + + > .left-arrow-preview-image { + opacity: 1; + } + } + + > .nav-right { + @extend .nav; + margin-left: $nav-side-margin; + right: 10px; + + > .right-arrow-preview-image { + opacity: 1; + } + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel.component.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel.component.spec.ts new file mode 100644 index 00000000..677be460 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel.component.spec.ts @@ -0,0 +1,863 @@ +/* + * Copyright (C) 2017-2024 Stefano Cappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentFixture, discardPeriodicTasks, fakeAsync, flush, TestBed, tick } from '@angular/core/testing'; + +import { DebugElement, SimpleChanges } from '@angular/core'; +import { By } from '@angular/platform-browser'; + +import { CarouselComponent } from './carousel.component'; +import { CarouselPreviewsComponent } from './carousel-previews/carousel-previews.component'; +import { SizeDirective } from '../../directives/size.directive'; +import { ModalGalleryComponent } from '../modal-gallery/modal-gallery.component'; +import { DescriptionDirective } from '../../directives/description.directive'; +import { DotsComponent } from '../dots/dots.component'; +import { MaxSizeDirective } from '../../directives/max-size.directive'; +import { PlainGalleryComponent } from '../plain-gallery/plain-gallery.component'; +import { ClickOutsideDirective } from '../../directives/click-outside.directive'; +import { UpperButtonsComponent } from '../upper-buttons/upper-buttons.component'; +import { CurrentImageComponent } from '../current-image/current-image.component'; +import { LoadingSpinnerComponent } from '../current-image/loading-spinner/loading-spinner.component'; +import { PreviewsComponent } from '../previews/previews.component'; +import { KeyboardNavigationDirective } from '../../directives/keyboard-navigation.directive'; +import { ATagBgImageDirective } from '../../directives/a-tag-bg-image.directive'; +import { WrapDirective } from '../../directives/wrap.directive'; +import { DirectionDirective } from '../../directives/direction.directive'; +import { IdValidatorService } from '../../services/id-validator.service'; +import { Image } from '../../model/image.class'; +import { CarouselConfig } from '../../model/carousel-config.interface'; +import { PlayConfig } from '../../model/play-config.interface'; +import { KS_DEFAULT_ACCESSIBILITY_CONFIG } from '../accessibility-default'; +import { AccessibilityConfig } from '../../model/accessibility.interface'; +import { Description, DescriptionStrategy, DescriptionStyle } from '../../model/description.interface'; +import { CarouselImageConfig } from '../../model/carousel-image-config.interface'; +import { getIndex } from '../../utils/image.util'; +import { CarouselPreviewConfig } from '../../model/carousel-preview-config.interface'; +import { ConfigService } from '../../services/config.service'; +import { FallbackImageDirective } from '../../directives/fallback-image.directive'; +import { OverlayModule } from '@angular/cdk/overlay'; +import { ModalGalleryService } from '../modal-gallery/modal-gallery.service'; + +const GALLERY_ID = 1; + +let comp: CarouselComponent; +let fixture: ComponentFixture; + +interface TestModel { + currentImgTitle: string; + currentAlt: string; + currentDescription: string; + currentImgAriaLabel: string; +} + +const TEST_MODEL: TestModel[] = [ + { + currentImgTitle: 'Image 1/7 - Description 1', + currentAlt: 'Description 1', + currentDescription: 'Image 1/7 - Description 1', + currentImgAriaLabel: 'First image aria-label' + }, + { + currentImgTitle: 'Image 2/7', + currentAlt: 'Image 2', + currentDescription: 'Image 2', + currentImgAriaLabel: 'ariaLabel' + }, + { + currentImgTitle: 'Third image title', + currentAlt: 'Third image alt', + currentDescription: 'Image 3/7 - Description 3', + currentImgAriaLabel: 'Third image aria-label' + }, + { + currentImgTitle: 'Fourth image title (modal obj)', + currentAlt: 'Fourth image alt (modal obj)', + currentDescription: 'Image 4/7 - Description 4', + currentImgAriaLabel: 'Fourth image aria-label (modal obj)' + }, + { + currentImgTitle: 'Image 5/7', + currentAlt: 'Image 5', + currentDescription: 'Image 5/7', + currentImgAriaLabel: 'ariaLabel' + }, + { + currentImgTitle: 'Image 6/7 - Description 6', + currentAlt: 'Description 6', + currentDescription: 'Image 6/7 - Description 6', + currentImgAriaLabel: 'ariaLabel' + }, + { + currentImgTitle: 'Image 7/7', + currentAlt: 'Image 7', + currentDescription: 'Image 7/7', + currentImgAriaLabel: 'ariaLabel' + } +]; + +const IMAGES: Image[] = [ + new Image( + 0, + { + img: '/assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1' + }, + { + img: '/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', + title: 'First image title', + alt: 'First image alt', + ariaLabel: 'First image aria-label' + } + ), + new Image(1, {img: '/assets/images/gallery/pexels-photo-47223.jpeg'}, {img: '/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg'}), + new Image( + 2, + { + img: '/assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3', + title: 'Third image title', + alt: 'Third image alt', + ariaLabel: 'Third image aria-label' + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '/assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4', + title: 'Fourth image title (modal obj)', + alt: 'Fourth image alt (modal obj)', + ariaLabel: 'Fourth image aria-label (modal obj)' + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', + title: 'Fourth image title (plain obj)', + alt: 'Fourth image alt (plain obj)', + ariaLabel: 'Fourth image aria-label (plain obj)' + } + ), + new Image(4, {img: '/assets/images/gallery/pexels-photo-93750.jpeg'}, {img: '/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg'}), + new Image( + 5, + { + img: '/assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6' + }, + {img: '/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg'} + ), + new Image(6, {img: '/assets/images/gallery/pexels-photo-96947.jpeg'}, {img: '/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg'}) +]; + +const ID_ERROR = 'Internal library error - id must be defined'; + +const CUSTOM_ACCESSIBILITY: AccessibilityConfig = Object.assign({}, KS_DEFAULT_ACCESSIBILITY_CONFIG); +CUSTOM_ACCESSIBILITY.carouselContainerAriaLabel = 'carouselContainerAriaLabel'; +CUSTOM_ACCESSIBILITY.carouselContainerTitle = 'carouselContainerTitle'; +CUSTOM_ACCESSIBILITY.carouselPrevImageAriaLabel = 'carouselPrevImageAriaLabel'; +CUSTOM_ACCESSIBILITY.carouselPrevImageTitle = 'carouselPrevImageTitle'; +CUSTOM_ACCESSIBILITY.carouselNextImageAriaLabel = 'carouselNextImageAriaLabel'; +CUSTOM_ACCESSIBILITY.carouselNextImageTitle = 'carouselNextImageTitle'; +CUSTOM_ACCESSIBILITY.dotsContainerAriaLabel = 'dotsContainerAriaLabel'; +CUSTOM_ACCESSIBILITY.dotsContainerTitle = 'dotsContainerTitle'; +CUSTOM_ACCESSIBILITY.carouselPreviewsContainerAriaLabel = 'carouselPreviewsContainerAriaLabel'; +CUSTOM_ACCESSIBILITY.carouselPreviewsContainerTitle = 'carouselPreviewsContainerTitle'; +CUSTOM_ACCESSIBILITY.carouselPreviewScrollPrevAriaLabel = 'carouselPreviewScrollPrevAriaLabel'; +CUSTOM_ACCESSIBILITY.carouselPreviewScrollPrevTitle = 'carouselPreviewScrollPrevTitle'; +CUSTOM_ACCESSIBILITY.carouselPreviewScrollNextAriaLabel = 'carouselPreviewScrollNextAriaLabel'; +CUSTOM_ACCESSIBILITY.carouselPreviewScrollNextTitle = 'carouselPreviewScrollNextTitle'; + +const DEFAULT_CAROUSEL_CONFIG: CarouselConfig = { + maxWidth: '100%', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false +}; + +function containsClasses(actualClasses: string, expectedClasses: string): boolean { + const actual: string[] = actualClasses.split(' '); + const expected: string[] = expectedClasses.split(' '); + let count = 0; + if (actual.length !== expected.length) { + return false; + } + expected.forEach((item: string) => { + if (actual.includes(item)) { + count++; + } + }); + return count === expected.length; +} + +function initTestBed(): void { + TestBed.configureTestingModule({ + imports: [OverlayModule], + declarations: [ + ClickOutsideDirective, + UpperButtonsComponent, CurrentImageComponent, LoadingSpinnerComponent, + PreviewsComponent, FallbackImageDirective, + KeyboardNavigationDirective, ATagBgImageDirective, + WrapDirective, DirectionDirective, + CarouselComponent, CarouselPreviewsComponent, ModalGalleryComponent, PlainGalleryComponent, + SizeDirective, DescriptionDirective, DotsComponent, MaxSizeDirective] + }).overrideComponent(CarouselComponent, { + set: { + providers: [ + { + provide: ConfigService, + useClass: ConfigService + }, + { + provide: ModalGalleryService, + useClass: ModalGalleryService + }, + { + provide: IdValidatorService, + useClass: IdValidatorService + } + ] + } + }); +} + +function checkMainContainer(maxWidth: string = '100%', accessibilityConfig: AccessibilityConfig = KS_DEFAULT_ACCESSIBILITY_CONFIG): void { + const element: DebugElement = fixture.debugElement; + const mainCarouselContainer: DebugElement = element.query(By.css('main#carousel-container')); + expect(mainCarouselContainer.name).toBe('main'); + expect(mainCarouselContainer.properties.title).toBe(accessibilityConfig.carouselContainerTitle); + expect(mainCarouselContainer.attributes['aria-label']).toBe(accessibilityConfig.carouselContainerAriaLabel); + // expect(mainCarouselContainer.attributes['style']).toBe('max-width: 100%;'); + + if (maxWidth !== '100%') { + expect(mainCarouselContainer.styles['max-width']).toBe(maxWidth); + } +} + +function checkCurrentImage(currentImage: Image, val: TestModel, withDots: boolean = true, withArrows: boolean = true, accessibilityConfig: AccessibilityConfig = KS_DEFAULT_ACCESSIBILITY_CONFIG): void { + const element: DebugElement = fixture.debugElement; + const currentFigure: DebugElement = element.query(By.css('figure.current-figure')); + expect(currentFigure.name).toBe('figure'); + const currentPictureElement: DebugElement = currentFigure.children[withArrows ? 1 : 0]; // 0 and 2 are the arrows + expect(currentPictureElement.name).toBe('picture'); + expect(currentPictureElement.attributes.class).toBe('current-image'); + const currentImageElement = currentPictureElement.children[0]; + expect(currentImageElement.name).toBe('img'); + expect(currentImageElement.attributes.role).toBe('img'); + expect(currentImageElement.properties.src).toBe(currentImage.modal.img); + expect(currentImageElement.properties.title).toBe(val.currentImgTitle); + expect(currentImageElement.properties.alt).toBe(val.currentAlt); + expect(currentImageElement.properties.tabIndex).toBe(0); + + if (withDots) { + const dotsMainContainer: DebugElement = element.query(By.css('div#dots')); + expect(dotsMainContainer.name).toBe('div'); + const dotsContainer: DebugElement = element.query(By.css('nav.dots-container')); + expect(dotsContainer.name).toBe('nav'); + expect(dotsContainer.attributes['aria-label']).toBe(accessibilityConfig.dotsContainerAriaLabel); + expect(dotsContainer.properties.title).toBe(accessibilityConfig.dotsContainerTitle); + const dots: DebugElement[] = dotsContainer.children; + expect(dots.length).toBe(IMAGES.length); + + const activeDotIndex = 0; + dots.forEach((dot: DebugElement, index: number) => { + expect(dot.name).toBe('div'); + expect(dot.attributes.role).toBe('navigation'); + expect(dot.properties.tabIndex).toBe(0); + if (index === activeDotIndex) { + // I don't know why, but with dot.attributes.class I can't see 'active'. In this way it's working! + // TODO fix this because is not working as expected. This line is ok, but tests aren't restarting from image 0 + // expect(dot.classes).toEqual({'inside': true, 'dot': true, 'active': true}); + } else { + // TODO tests aren't restarting from image 0 so I have to admit both active and inactive dots + expect(containsClasses(dot.attributes.class as string, 'inside dot') || + containsClasses(dot.attributes.class as string, 'inside dot active')).toBeTrue(); + // or like above: expect(dot.classes).toEqual({'inside': true, 'dot': true}); + } + expect(dot.attributes['aria-label']).toBe(accessibilityConfig.dotAriaLabel + ' ' + (index + 1)); + }); + } +} + +function checkDescription(currentImage: Image, carouselImageConfig: CarouselImageConfig): void { + const element: DebugElement = fixture.debugElement; + const currentFigcaption: DebugElement = element.query(By.css('figcaption.description')); + if (carouselImageConfig.description && carouselImageConfig.description.strategy !== DescriptionStrategy.ALWAYS_HIDDEN) { + expect(currentFigcaption.attributes.class).toBe('description'); + // TODO check style background: rgba(0, 0, 0, 0.5); color: white; margin: 0px; + expect(currentFigcaption.nativeElement.textContent).toEqual(getDescriptionToDisplay(carouselImageConfig.description.strategy, currentImage, carouselImageConfig)); + } +} + +function getDescriptionToDisplay(descStrategy: DescriptionStrategy, image: Image, carouselImageConfig: CarouselImageConfig): string { + const imageWithoutDescription: boolean = !image.modal || !image.modal.description || image.modal.description === ''; + + switch (descStrategy) { + case DescriptionStrategy.HIDE_IF_EMPTY: + return imageWithoutDescription ? '' : image.modal.description + ''; + case DescriptionStrategy.ALWAYS_HIDDEN: + return ''; + default: + // ----------- DescriptionStrategy.ALWAYS_VISIBLE ----------------- + return buildTextDescription(image, imageWithoutDescription, carouselImageConfig); + } +} + +function buildTextDescription(image: Image, imageWithoutDescription: boolean, carouselImageConfig: CarouselImageConfig): string { + // // If customFullDescription use it, otherwise proceed to build a description + // if (this.configCurrentImageCarousel.description.customFullDescription && this.configCurrentImageCarousel.description.customFullDescription !== '') { + // return this.configCurrentImageCarousel.description.customFullDescription; + // } + + const currentIndex: number = getIndex(image, IMAGES); + // If the current image hasn't a description, + // prevent to write the ' - ' (or this.description.beforeTextDescription) + + const prevDescription: string = carouselImageConfig.description?.imageText ? carouselImageConfig.description.imageText : ''; + const midSeparator: string = carouselImageConfig.description?.numberSeparator + ? carouselImageConfig.description.numberSeparator + : ''; + const middleDescription: string = currentIndex + 1 + midSeparator + IMAGES.length; + + if (imageWithoutDescription) { + return prevDescription + middleDescription; + } + + const currImgDescription: string = image.modal && image.modal.description ? image.modal.description : ''; + // return currImgDescription; // TODO remove this + const endDescription: string = carouselImageConfig.description?.beforeTextDescription + currImgDescription; + return prevDescription + middleDescription + endDescription; +} + +function checkArrows(isFirstImage: boolean, isLastImage: boolean, accessibilityConfig: AccessibilityConfig = KS_DEFAULT_ACCESSIBILITY_CONFIG): void { + const element: DebugElement = fixture.debugElement; + const aNavLeft: DebugElement = element.query(By.css('a.nav-left')); + expect(aNavLeft.name).toBe('a'); + expect(aNavLeft.attributes.role).toBe('button'); + expect(aNavLeft.attributes['aria-label']).toBe(accessibilityConfig.carouselPrevImageAriaLabel); + expect(aNavLeft.properties.tabIndex).toBe(isFirstImage ? -1 : 0); + const divNavLeft: DebugElement = aNavLeft.children[0]; + expect(divNavLeft.attributes['aria-hidden']).toBe('true'); + expect(containsClasses(divNavLeft.properties.className, 'inside ' + (isFirstImage ? 'empty-arrow-image' : 'left-arrow-image'))).toBeTrue(); + expect(divNavLeft.properties.title).toBe(accessibilityConfig.carouselPrevImageTitle); + + const aNavRight: DebugElement = element.query(By.css('a.nav-right')); + expect(aNavRight.name).toBe('a'); + expect(aNavRight.attributes.role).toBe('button'); + expect(aNavRight.attributes['aria-label']).toBe(accessibilityConfig.carouselNextImageAriaLabel); + expect(aNavRight.properties.tabIndex).toBe(isLastImage ? -1 : 0); + const divNavRight: DebugElement = aNavRight.children[0]; + expect(divNavRight.attributes['aria-hidden']).toBe('true'); + expect(containsClasses(divNavRight.properties.className, 'inside ' + (isLastImage ? 'empty-arrow-image' : 'right-arrow-image'))).toBeTrue(); + expect(divNavRight.properties.title).toBe(accessibilityConfig.carouselNextImageTitle); +} + +function checkPreviews(numPreviews: number, isFirstImage: boolean, isLastImage: boolean, clickable: boolean, accessibilityConfig: AccessibilityConfig = KS_DEFAULT_ACCESSIBILITY_CONFIG): void { + const element: DebugElement = fixture.debugElement; + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(accessibilityConfig.carouselPreviewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(accessibilityConfig.carouselPreviewsContainerTitle); + + const aNavLeft: DebugElement = element.query(By.css('a.nav-left')); + const divNavLeft: DebugElement = aNavLeft.children[0]; + expect(divNavLeft.name).toBe('div'); + expect(divNavLeft.attributes['aria-hidden']).toBe('true'); + expect(containsClasses(divNavLeft.properties.className, 'inside ' + (isFirstImage ? 'empty-arrow-image' : 'left-arrow-image'))).toBeTrue(); + // TODO fixme + // expect(divNavLeft.attributes['aria-label']).toBe(accessibilityConfig.carouselPreviewScrollPrevAriaLabel); + // expect(divNavLeft.properties.title).toBe(accessibilityConfig.carouselPreviewScrollPrevTitle); + + const aNavRight: DebugElement = element.query(By.css('a.nav-right')); + const divNavRight: DebugElement = aNavRight.children[0]; + expect(divNavRight.name).toBe('div'); + expect(divNavRight.attributes['aria-hidden']).toBe('true'); + expect(containsClasses(divNavRight.properties.className, 'inside ' + (isFirstImage ? 'empty-arrow-image' : 'right-arrow-image'))).toBeTrue(); + // TODO fixme + // expect(divNavRight.attributes['aria-label']).toBe(accessibilityConfig.carouselPreviewScrollNextAriaLabel); + // expect(divNavRight.properties.title).toBe(accessibilityConfig.carouselPreviewScrollNextTitle); + + const previewsInner: DebugElement = element.query(By.css('div.preview-inner-container')); + expect(previewsInner.name).toBe('div'); + const previews: DebugElement[] = previewsInner.children; + expect(previews.length).toBe(numPreviews); + previews.forEach((preview: DebugElement, index: number) => { + expect(preview.attributes.role).toBe('img'); + expect(containsClasses(preview.properties.className, 'inside preview-image' + (index === 0 ? ' active' : '') + (clickable ? '' : ' unclickable'))).toBeTrue(); + expect(preview.properties.tabIndex).toBe(0); + // expect(preview.properties['style']).toBe('width: 25%; height: 200px;'); + // expect(preview.properties.src).toBe(previewsContainer.modal.img); + // expect(preview.attributes['aria-label']).toBe(); + // expect(preview.properties.title).toBe(); + // expect(preview.properties.alt).toBe(); + }); +} + +describe('CarouselComponent', () => { + beforeEach(() => { + initTestBed(); + fixture = TestBed.createComponent(CarouselComponent); + comp = fixture.componentInstance; + }); + + it('should instantiate it', () => expect(comp).not.toBeNull()); + + + // should navigate between images clicking on current image. Test i=0 + // should navigate between images clicking on right side preview. Test i=0 + // should navigate between images to the right using swipe gestures. Test i=0 + + describe('---YES---', () => { + + it(`should display carousel with all defaults and auto-navigate (play enabled by default).`, fakeAsync(() => { + comp.id = GALLERY_ID; + comp.images = IMAGES; + fixture.detectChanges(); + const defaultInterval = 5000; + + TEST_MODEL.forEach((val: TestModel, index: number) => { + checkMainContainer(); + checkCurrentImage(IMAGES[index], val); + checkArrows(false, false); + tick(defaultInterval + 100); + flush(); + fixture.detectChanges(); + }); + + tick(defaultInterval + 100); + flush(); + fixture.detectChanges(); + + discardPeriodicTasks(); + })); + + it(`should display carousel with all defaults and auto-navigate (play enabled by default) trying infinite sliding.`, fakeAsync(() => { + comp.id = GALLERY_ID; + comp.images = IMAGES; + fixture.detectChanges(); + const defaultInterval = 5000; + + TEST_MODEL.forEach((val: TestModel, index: number) => { + checkMainContainer(); + checkCurrentImage(IMAGES[index], val); + checkArrows(false, false); + tick(defaultInterval + 100); + flush(); + fixture.detectChanges(); + }); + + // check the first image (because of infinite sliding) + checkMainContainer(); + checkCurrentImage(IMAGES[0], TEST_MODEL[0]); + checkArrows(false, false); + tick(defaultInterval + 100); + flush(); + fixture.detectChanges(); + + discardPeriodicTasks(); + })); + + it(`should display carousel no infinite and auto-navigate.`, fakeAsync(() => { + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { carouselSlideInfinite: false }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + fixture.detectChanges(); + + const defaultInterval = 5000; + + TEST_MODEL.forEach((val: TestModel, index: number) => { + checkMainContainer(); + checkCurrentImage(IMAGES[index], val); + // checkArrows(index === 0, index === 6); + tick(defaultInterval + 100); + flush(); + fixture.detectChanges(); + }); + + // infinite sliding is disabled, so after the next interval, current image must be still the last one + checkMainContainer(); + checkCurrentImage(IMAGES[6], TEST_MODEL[6]); + // checkArrows(false, true); + tick(defaultInterval + 100); + flush(); + fixture.detectChanges(); + + discardPeriodicTasks(); + })); + + it(`should display carousel without dots.`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { carouselDotsConfig: {visible: false} }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + fixture.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[0], TEST_MODEL[0], false, true); + checkArrows(false, false); + }); + + it(`should display carousel without arrows.`, fakeAsync(() => { + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { carouselConfig: Object.assign({}, DEFAULT_CAROUSEL_CONFIG, {showArrows: false}) }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[0], TEST_MODEL[0], false, false); + + discardPeriodicTasks(); + })); + + const PLAY_CONFIG_AUTOPLAY: PlayConfig[] = [ + {autoPlay: true, interval: 5000, pauseOnHover: true}, + {autoPlay: true, interval: 1000, pauseOnHover: true}, + {autoPlay: true, interval: 10000, pauseOnHover: true}, + {autoPlay: true, interval: 10, pauseOnHover: true}, + {autoPlay: true, interval: 1000, pauseOnHover: false} + ]; + + PLAY_CONFIG_AUTOPLAY.forEach((val: PlayConfig, index: number) => { + it(`should display carousel with autoplay enabled, but with different combinations of interval and pauseOnHover. Test i=${index}`, fakeAsync(() => { + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { carouselPlayConfig: val }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + fixture.detectChanges(); + + TEST_MODEL.forEach((model: TestModel, modelIndex: number) => { + checkMainContainer(); + checkCurrentImage(IMAGES[modelIndex], model); + checkArrows(false, false); + tick(val.interval + 1); + flush(); + fixture.detectChanges(); + }); + + tick(val.interval + 1); + flush(); + fixture.detectChanges(); + + discardPeriodicTasks(); + })); + }); + + const PLAY_CONFIG_NO_AUTOPLAY: PlayConfig[] = [ + {autoPlay: false, interval: 1000, pauseOnHover: true}, + {autoPlay: false, interval: 10000, pauseOnHover: false} + ]; + + PLAY_CONFIG_NO_AUTOPLAY.forEach((val: PlayConfig, index: number) => { + it(`should display carousel without autoplay. Test i=${index}`, fakeAsync(() => { + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { carouselPlayConfig: val }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + fixture.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[0], TEST_MODEL[0]); + checkArrows(false, false); + tick(val.interval + 100); + flush(); + fixture.detectChanges(); + + // after interval, the current image must be again the first image (because autoplay is disabled) + checkMainContainer(); + // TODO uncomment this + // checkCurrentImage(IMAGES[0], TEST_MODEL[0]); + checkArrows(false, false); + tick(val.interval + 100); + flush(); + fixture.detectChanges(); + + discardPeriodicTasks(); + })); + }); + + const PREVIEW_CONFIGS: CarouselPreviewConfig[] = [ + {visible: true}, + {visible: true, clickable: true}, + {visible: true, clickable: false}, + {visible: true, number: 7}, + // {visible: true, number: 0}, + // {visible: true, number: -1}, + {visible: true, number: 4, width: 'auto', maxHeight: '100px'}, + {visible: true, number: 4, width: 'auto', maxHeight: '100px'}, + {visible: true, number: 4, width: '100px', maxHeight: '100px'} + ]; + + PREVIEW_CONFIGS.forEach((val: CarouselPreviewConfig, index: number) => { + it(`should display carousel with previews. Test i=${index}`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { carouselPreviewsConfig: val }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + fixture.detectChanges(); + + checkPreviews(val.number || 4, false, false, val.clickable === true || val.clickable === undefined); + }); + }); + + it(`should display carousel with fixed width.`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { + carouselConfig: Object.assign({}, DEFAULT_CAROUSEL_CONFIG, {maxWidth: '766px'}), + carouselPreviewsConfig: {number: 5, width: 'auto', maxHeight: '100px', visible: true} + }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + checkMainContainer(comp.carouselConfig?.maxWidth); + checkCurrentImage(IMAGES[0], TEST_MODEL[0]); + checkArrows(false, false); + }); + + const defaultDescriptionStyle: DescriptionStyle = { + bgColor: 'rgba(0, 0, 0, .5)', + textColor: 'white', + marginTop: '0px', + marginBottom: '0px', + marginLeft: '0px', + marginRight: '0px' + }; + + const carouselImageConfigs: CarouselImageConfig[] = [ + { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + imageText: 'Image ', + numberSeparator: '/', + beforeTextDescription: ' - ', + style: defaultDescriptionStyle + } as Description + }, + { + description: { + strategy: DescriptionStrategy.ALWAYS_HIDDEN, + imageText: 'Image ', + numberSeparator: '/', + beforeTextDescription: ' - ', + style: defaultDescriptionStyle + } as Description + }, + { + description: { + strategy: DescriptionStrategy.HIDE_IF_EMPTY, + imageText: 'Image ', + numberSeparator: '/', + beforeTextDescription: ' - ', + style: defaultDescriptionStyle + } as Description + } + ]; + + carouselImageConfigs.forEach((val: CarouselImageConfig, index: number) => { + it(`should display carousel with description. Test i=${index}`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { carouselImageConfig: val }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + fixture.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[0], TEST_MODEL[0]); + checkDescription(IMAGES[0], val); + checkArrows(false, false); + }); + }); + + const PREVIEW_CONFIGS_BREAKPOINT: CarouselPreviewConfig[] = [ + {visible: true, breakpoints: {xSmall: 50, small: 60, medium: 80, large: 150, xLarge: 180}}, + {visible: true, breakpoints: {xSmall: 100, small: 120, medium: 150, large: 200, xLarge: 220}}, + {visible: true, breakpoints: {xSmall: 200, small: 220, medium: 10, large: 50, xLarge: 100}}, + // zero or negative numbers are admitted in the code, but they are completely useless for the user + // however, I should improve this + {visible: true, breakpoints: {xSmall: 0, small: 0, medium: 0, large: 0, xLarge: 0}}, + {visible: true, breakpoints: {xSmall: -1, small: -2, medium: -10, large: -10, xLarge: -1}} + ]; + + PREVIEW_CONFIGS_BREAKPOINT.forEach((previewConfig: CarouselPreviewConfig, index: number) => { + it(`should display carousel with custom breakpoints.`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { carouselPreviewsConfig: previewConfig }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + fixture.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[0], TEST_MODEL[0]); + checkArrows(false, false); + }); + }); + + it(`should display carousel with custom accessibility.`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { accessibilityConfig: CUSTOM_ACCESSIBILITY }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + checkMainContainer('100%', CUSTOM_ACCESSIBILITY); + checkCurrentImage(IMAGES[0], TEST_MODEL[0], true, true, CUSTOM_ACCESSIBILITY); + checkArrows(false, false, CUSTOM_ACCESSIBILITY); + }); + + // // TODO not working, why??? + // it(`should display carousel and open modal-gallery clicking on the current image.`, () => { + // comp.id = GALLERY_ID; + // comp.images = IMAGES; + // comp.carouselConfig = { + // maxWidth: '100%', + // maxHeight: '200px', + // showArrows: true, + // objectFit: 'cover', + // keyboardEnable: true, + // modalGalleryEnable: true, // modalGalleryEnable is required in this test + // legacyIE11Mode: false + // }; + // comp.ngOnInit(); + // fixture.detectChanges(); + // + // checkMainContainer(); + // checkCurrentImage(IMAGES[0], TEST_MODEL[0]); + // checkArrows(false, false); + // // tick(defaultInterval + 100); + // // fixture.detectChanges(); + // + // // click on the current image + // const element: DebugElement = fixture.debugElement; + // const currentImage: DebugElement = element.query(By.css('picture.current-image>img')); + // console.log('currentImage', currentImage); + // + // currentImage.nativeElement.click(); + // + // + // fixture.detectChanges(); + // + // const modalGalleryWrapper: DebugElement = element.query(By.css('#modal-gallery-wrapper')); + // console.log('modalGalleryWrapper', modalGalleryWrapper); + // expect(modalGalleryWrapper).not.toBeNull(); + // }); + + // it(`should display carousel without autoplay and navigate between images clicking on arrows.`, fakeAsync(() => { + // comp.id = GALLERY_ID; + // comp.images = IMAGES; + // comp.ngOnInit(); + // fixture.detectChanges(); + // + // comp.show.subscribe((res: ImageModalEvent) => { + // console.log('^^^^^^^^^^^^^^^^^^^^^^ show called res', res); + // // checkMainContainer(); + // // checkCurrentImage(IMAGES[1], TEST_MODEL[1]); + // // checkArrows(false, false); + // // comp.nextImage(Action.CLICK); + // // tick(defaultInterval + 100); + // fixture.detectChanges(); + // }); + // + // // TEST_MODEL.forEach((val: TestModel, index: number) => { + // checkMainContainer(); + // checkCurrentImage(IMAGES[0], TEST_MODEL[0]); + // checkArrows(false, false); + // // comp.nextImage(Action.CLICK); + // // tick(defaultInterval + 100); + // fixture.detectChanges(); + // discardPeriodicTasks(); + // // }); + // })); + + // TODO improve this adding more cases to cover all lines of code + it(`should open carousel calling also ngOnChanges.`, fakeAsync(() => { + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.ngOnChanges({ + currentImage: { + previousValue: IMAGES[0], + currentValue: IMAGES[0], + firstChange: false, + isFirstChange: () => false + } + } as SimpleChanges); + fixture.detectChanges(); + const defaultInterval = 5000; + + TEST_MODEL.forEach((val: TestModel, index: number) => { + checkMainContainer(); + checkCurrentImage(IMAGES[index], val); + checkArrows(false, false); + tick(defaultInterval + 100); + flush(); + fixture.detectChanges(); + }); + + tick(defaultInterval + 100); + flush(); + fixture.detectChanges(); + + discardPeriodicTasks(); + })); + }); + + describe('---ERRORS---', () => { + it(`should throw an error, because id is not valid.`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { carouselConfig: Object.assign({}, DEFAULT_CAROUSEL_CONFIG, {modalGalleryEnable: true}) }); + comp.id = undefined; + comp.images = IMAGES; + expect(() => comp.ngOnInit()).toThrow(new Error(ID_ERROR)); + }); + + const PLAY_CONFIG_AUTOPLAY: PlayConfig[] = [ + {autoPlay: true, interval: 0, pauseOnHover: true}, + {autoPlay: true, interval: -10, pauseOnHover: false}, + {autoPlay: true, interval: -1000, pauseOnHover: true}, + {autoPlay: false, interval: 0, pauseOnHover: false}, + {autoPlay: false, interval: -10, pauseOnHover: true}, + {autoPlay: false, interval: -1000, pauseOnHover: false} + ]; + + PLAY_CONFIG_AUTOPLAY.forEach((val: PlayConfig, index: number) => { + it(`should throw an error because playConfig.interval is <=0. Test i=${index}`, fakeAsync(() => { + const configService = fixture.debugElement.injector.get(ConfigService); + + expect(() => configService.setConfig(GALLERY_ID, { carouselPlayConfig: val })).toThrow(new Error(`Carousel's interval must be a number >= 0`)); + discardPeriodicTasks(); + })); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel.component.ts b/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel.component.ts new file mode 100644 index 00000000..7c343814 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel.component.ts @@ -0,0 +1,832 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +// The idea to create a carousel with two Subjects came from ng-bootstrap +// So a big thank you to the ng-bootstrap team for the interesting implementation that I used here with some customizations. + +import { + AfterContentInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + EventEmitter, + HostBinding, + HostListener, + Inject, + Input, + NgZone, + OnChanges, + OnDestroy, + OnInit, + Output, + PLATFORM_ID, + SimpleChange, + SimpleChanges +} from '@angular/core'; +import { isPlatformBrowser } from '@angular/common'; + +import { Subject, timer } from 'rxjs'; +import { filter, map, switchMap, takeUntil } from 'rxjs/operators'; + +import { AccessibleComponent } from '../accessible.component'; + +import { AccessibilityConfig } from '../../model/accessibility.interface'; +import { Image, ImageEvent } from '../../model/image.class'; +import { Action } from '../../model/action.enum'; +import { getIndex } from '../../utils/image.util'; +import { NEXT, PREV } from '../../utils/user-input.util'; +import { DescriptionStrategy } from '../../model/description.interface'; +import { DotsConfig } from '../../model/dots-config.interface'; +import { CarouselConfig } from '../../model/carousel-config.interface'; +import { CarouselImageConfig } from '../../model/carousel-image-config.interface'; +import { ConfigService } from '../../services/config.service'; +import { ModalGalleryService } from '../modal-gallery/modal-gallery.service'; +import { CarouselLibConfig, LibConfig } from '../../model/lib-config.interface'; +import { InternalLibImage } from '../../model/image-internal.class'; + +/** + * Component with configurable inline/plain carousel. + */ +@Component({ + selector: 'ks-carousel', + styleUrls: ['carousel.scss', '../image-arrows.scss'], + templateUrl: 'carousel.html', + changeDetection: ChangeDetectionStrategy.OnPush, + providers: [ConfigService], + standalone: false +}) +export class CarouselComponent extends AccessibleComponent implements OnInit, AfterContentInit, OnDestroy, OnChanges { + /** + * Attribute to set ariaLabel of the host component + */ + @HostBinding('attr.aria-label') + ariaLabel = `Carousel`; + /** + * Unique id (>=0) of the current instance of the carousel. This is useful when you are using + * the carousel's feature to open modal gallery. + */ + @Input() + id: number | undefined; + /** + * Array of `InternalLibImage` that represent the model of this library with all images, + * thumbs and so on. + */ + @Input() + images: Image[] = []; + /** + * CarouselLibConfig object to configure carousel. + */ + @Input() + config: CarouselLibConfig | undefined; + + /** + * Output to emit an event when an image is clicked. + */ + @Output() + clickImage: EventEmitter = new EventEmitter(); + /** + * Output to emit an event when current image is changed. + */ + @Output() + changeImage: EventEmitter = new EventEmitter(); + /** + * Output to emit an event when the current image is the first one. + */ + @Output() + firstImage: EventEmitter = new EventEmitter(); + /** + * Output to emit an event when the current image is the last one. + */ + @Output() + lastImage: EventEmitter = new EventEmitter(); + + /** + * Object of type `CarouselConfig` to init CarouselComponent's features. + * For instance, it contains parameters to change the style, how it navigates and so on. + */ + carouselConfig: CarouselConfig | undefined; + + /** + * Object of type `DotsConfig` to init DotsComponent's features. + * For instance, it contains a param to show/hide this component. + */ + carouselDotsConfig: DotsConfig | undefined; + /** + * Object of type `AccessibilityConfig` to init custom accessibility features. + * For instance, it contains titles, alt texts, aria-labels and so on. + */ + accessibilityConfig: AccessibilityConfig | undefined; + /** + * Object of type `CarouselImageConfig` to configure the current image of the carousel. + */ + carouselImageConfig: CarouselImageConfig | undefined; + /** + * Enable/disable infinite sliding. + */ + carouselSlideInfinite: boolean | undefined; + + /** + * Enum of type `Action` that represents a mouse click on a button. + * Declared here to be used inside the template. + */ + clickAction: Action = Action.CLICK; + /** + * Enum of type `Action` that represents a keyboard action. + * Declared here to be used inside the template. + */ + keyboardAction: Action = Action.KEYBOARD; + /** + * `Image` that is visible right now. + */ + currentImage: InternalLibImage | undefined; + /** + * Boolean that it's true when you are watching the first image (currently visible). + * False by default + */ + isFirstImage = false; + /** + * Boolean that it's true when you are watching the last image (currently visible). + * False by default + */ + isLastImage = false; + + /** + * Subject to play the carousel. + */ + private start$ = new Subject(); + /** + * Subject to stop the carousel. + */ + private stop$ = new Subject(); + + /** + * Listener to stop the gallery when the mouse pointer is over the current image. + */ + @HostListener('mouseenter') + onMouseEnter(): void { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + if (!libConfig.carouselPlayConfig || !libConfig.carouselPlayConfig.pauseOnHover) { + return; + } + this.stopCarousel(); + } + + /** + * Listener to play the gallery when the mouse pointer leave the current image. + */ + @HostListener('mouseleave') + onMouseLeave(): void { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + if (!libConfig.carouselPlayConfig || !libConfig.carouselPlayConfig.pauseOnHover || !libConfig.carouselPlayConfig.autoPlay) { + return; + } + this.playCarousel(); + } + + /** + * Listener to navigate carousel images with keyboard (left). + */ + @HostListener('keydown.arrowLeft') + onKeyDownLeft(): void { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + if (!libConfig.carouselConfig || !libConfig.carouselConfig.keyboardEnable) { + return; + } + this.prevImage(); + } + + /** + * Listener to navigate carousel images with keyboard (right). + */ + @HostListener('keydown.arrowRight') + onKeyDownLRight(): void { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + if (!libConfig.carouselConfig || !libConfig.carouselConfig.keyboardEnable) { + return; + } + this.nextImage(); + } + + constructor( + // tslint:disable-next-line:no-any + @Inject(PLATFORM_ID) private platformId: any, + private ngZone: NgZone, + private modalGalleryService: ModalGalleryService, + private configService: ConfigService, + private ref: ChangeDetectorRef + ) { + super(); + } + + ngOnInit(): void { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + if (!this.images || this.images.length === 0) { + throw new Error('Internal library error - images array must be defined and with at least an element'); + } + this.configService.setConfig(this.id, this.config); + + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + + this.currentImage = this.images[0] as InternalLibImage; + this.carouselDotsConfig = libConfig.carouselDotsConfig; + this.accessibilityConfig = libConfig.accessibilityConfig; + this.carouselSlideInfinite = libConfig.carouselSlideInfinite; + this.carouselConfig = libConfig.carouselConfig; + this.carouselImageConfig = libConfig.carouselImageConfig; + + this.manageSlideConfig(); + } + + ngOnChanges(changes: SimpleChanges): void { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + + // this.configService.setConfig(this.id, this.config); + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + + const configChange: SimpleChange = changes.config; + + // handle changes of dotsConfig.visible + if (configChange && + !configChange.firstChange && + (configChange.previousValue.carouselDotsConfig?.visible !== configChange.currentValue.carouselDotsConfig?.visible || (!configChange.previousValue.carouselDotsConfig && !configChange.currentValue.carouselDotsConfig)) + ) { + this.configService.setConfig(this.id, { + carouselDotsConfig: configChange.currentValue?.carouselDotsConfig + }); + this.carouselDotsConfig = configChange.currentValue?.carouselDotsConfig; + this.ref.markForCheck(); + } + // handle changes of carouselConfig.showArrows + if (configChange && + !configChange.firstChange && + (configChange.previousValue.carouselConfig?.showArrows !== configChange.currentValue.carouselConfig?.showArrows || (!configChange.previousValue.carouselConfig && !configChange.currentValue.carouselConfig)) + ) { + this.configService.setConfig(this.id, { + carouselConfig: configChange.currentValue?.carouselConfig + }); + this.carouselConfig = configChange.currentValue?.carouselConfig; + this.ref.markForCheck(); + } + // handle changes of playConfig starting/stopping the carousel accordingly + if (configChange && + !configChange.firstChange && + (configChange.previousValue.carouselPlayConfig?.autoPlay !== configChange.currentValue.carouselPlayConfig?.autoPlay || (!configChange.previousValue.carouselPlayConfig && !configChange.currentValue.carouselPlayConfig)) + ) { + this.configService.setConfig(this.id, { + carouselPlayConfig: configChange.currentValue?.carouselPlayConfig + }); + // this.configPlay = playConfigChange.currentValue; + // if autoplay is enabled, and this is not the + // first change (to prevent multiple starts at the beginning) + if (configChange.currentValue.carouselPlayConfig?.autoPlay && !configChange.firstChange) { + this.start$.next(); + } else { + this.stopCarousel(); + } + this.ref.markForCheck(); + } + } + + ngAfterContentInit(): void { + // interval doesn't play well with SSR and protractor, + // so we should run it in the browser and outside Angular + if (isPlatformBrowser(this.platformId)) { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig || !libConfig.carouselPlayConfig) { + throw new Error('Internal library error - libConfig and carouselPlayConfig must be defined'); + } + this.ngZone.runOutsideAngular(() => { + this.start$ + .pipe( + map(() => libConfig?.carouselPlayConfig?.interval), + // tslint:disable-next-line:no-any + filter((interval: any) => interval > 0), + switchMap(interval => timer(interval).pipe(takeUntil(this.stop$))) + ) + .subscribe(() => + this.ngZone.run(() => { + if (libConfig.carouselPlayConfig?.autoPlay) { + this.nextImage(); + } + this.ref.markForCheck(); + }) + ); + + this.start$.next(); + }); + } + } + + /** + * Method called when a dot is clicked and used to update the current image. + * @param number index of the clicked dot + */ + onClickDot(index: number): void { + this.changeCurrentImage(this.images[index] as InternalLibImage, Action.NORMAL); + } + + /** + * Method called by events from both keyboard and mouse on a navigation arrow. + * @param string direction of the navigation that can be either 'next' or 'prev' + * @param KeyboardEvent | MouseEvent event payload + * @param Action action that triggered the event or `Action.NORMAL` if not provided + */ + onNavigationEvent(direction: string, event: KeyboardEvent | MouseEvent, action: Action = Action.NORMAL): void { + const result: number = super.handleNavigationEvent(direction, event); + if (result === NEXT) { + this.nextImage(action); + } else if (result === PREV) { + this.prevImage(action); + } + } + + /** + * Method triggered when you click on the current image. + * Also, if modalGalleryEnable is true, you can open the modal-gallery. + */ + onClickCurrentImage(): void { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig || !libConfig.carouselConfig || !this.currentImage) { + throw new Error('Internal library error - libConfig, carouselConfig and currentImage must be defined'); + } + if (!libConfig.carouselConfig.modalGalleryEnable) { + return; + } + const index = getIndex(this.currentImage, this.images); + this.clickImage.emit(index); + } + + /** + * Method to get the image description based on input params. + * If you provide a full description this will be the visible description, otherwise, + * it will be built using the `Description` object, concatenating its fields. + * @param Image image to get its description. If not provided it will be the current image + * @returns String description of the image (or the current image if not provided) + * @throws an Error if description isn't available + */ + getDescriptionToDisplay(image: Image | undefined = this.currentImage): string { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + const configCurrentImageCarousel: CarouselImageConfig | undefined = libConfig.carouselImageConfig; + if (!configCurrentImageCarousel || !configCurrentImageCarousel.description) { + throw new Error('Description input must be a valid object implementing the Description interface'); + } + if (!image) { + throw new Error('Internal library error - image must be defined'); + } + const imageWithoutDescription: boolean = !image || !image.modal || !image.modal.description || image.modal.description === ''; + + switch (configCurrentImageCarousel.description.strategy) { + case DescriptionStrategy.HIDE_IF_EMPTY: + return imageWithoutDescription ? '' : image.modal.description + ''; + case DescriptionStrategy.ALWAYS_HIDDEN: + return ''; + default: + // ----------- DescriptionStrategy.ALWAYS_VISIBLE ----------------- + return this.buildTextDescription(image, imageWithoutDescription); + } + } + + /** + * Method used by SwipeDirective to support touch gestures (you can also invert the swipe direction with configCurrentImage.invertSwipe). + * @param action String that represent the direction of the swipe action. 'swiperight' by default. + */ + swipe(action = 'swiperight'): void { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig || !libConfig.carouselImageConfig) { + throw new Error('Internal library error - libConfig and carouselImageConfig must be defined'); + } + const configCurrentImageCarousel: CarouselImageConfig = libConfig.carouselImageConfig; + switch (action) { + case 'swiperight': + if (configCurrentImageCarousel.invertSwipe) { + this.prevImage(Action.SWIPE); + } else { + this.nextImage(Action.SWIPE); + } + break; + case 'swipeleft': + if (configCurrentImageCarousel.invertSwipe) { + this.nextImage(Action.SWIPE); + } else { + this.prevImage(Action.SWIPE); + } + break; + // case this.SWIPE_ACTION.UP: + // break; + // case this.SWIPE_ACTION.DOWN: + // break; + } + } + + /** + * Method to go back to the previous image. + * @param action Enum of type `Action` that represents the source + * action that moved back to the previous image. `Action.NORMAL` by default. + */ + prevImage(action: Action = Action.NORMAL): void { + // check if prevImage should be blocked + if (this.isPreventSliding(0)) { + return; + } + this.changeCurrentImage(this.getPrevImage(), action); + + this.manageSlideConfig(); + + this.start$.next(); + } + + /** + * Method to go back to the previous image. + * @param action Enum of type `Action` that represents the source + * action that moved to the next image. `Action.NORMAL` by default. + */ + nextImage(action: Action = Action.NORMAL): void { + // check if nextImage should be blocked + if (this.isPreventSliding(this.images.length - 1)) { + return; + } + this.changeCurrentImage(this.getNextImage(), action); + + this.manageSlideConfig(); + + this.start$.next(); + } + + /** + * Method used in the template to track ids in ngFor. + * @param number index of the array + * @param Image item of the array + * @returns number the id of the item + */ + trackById(index: number, item: Image): number { + return item.id; + } + + /** + * Method called when an image preview is clicked and used to update the current image. + * @param event an ImageEvent object with the relative action and the index of the clicked preview. + */ + onClickPreview(event: ImageEvent): void { + const imageFound: InternalLibImage = this.images[event.result as number] as InternalLibImage; + if (!!imageFound) { + this.manageSlideConfig(); + this.changeCurrentImage(imageFound, event.action); + } + } + + /** + * Method to play carousel. + */ + playCarousel(): void { + this.start$.next(); + } + + /** + * Stops the carousel from cycling through items. + */ + stopCarousel(): void { + this.stop$.next(); + } + + // TODO remove this because duplicated + /** + * Method to get `alt attribute`. + * `alt` specifies an alternate text for an image, if the image cannot be displayed. + * @param Image image to get its alt description. If not provided it will be the current image + * @returns String alt description of the image (or the current image if not provided) + */ + getAltDescriptionByImage(image: Image | undefined = this.currentImage): string { + if (!image) { + return ''; + } + return image.modal && image.modal.description ? image.modal.description : `Image ${getIndex(image, this.images) + 1}`; + } + + // TODO remove this because duplicated + /** + * Method to get the title attributes based on descriptions. + * This is useful to prevent accessibility issues, because if DescriptionStrategy is ALWAYS_HIDDEN, + * it prevents an empty string as title. + * @param Image image to get its description. If not provided it will be the current image + * @returns String title of the image based on descriptions + * @throws an Error if description isn't available + */ + getTitleToDisplay(image: Image | undefined = this.currentImage): string { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig || !libConfig.carouselImageConfig) { + throw new Error('Internal library error - libConfig and carouselImageConfig must be defined'); + } + const configCurrentImageCarousel: CarouselImageConfig = libConfig.carouselImageConfig; + if (!configCurrentImageCarousel || !configCurrentImageCarousel.description) { + throw new Error('Description input must be a valid object implementing the Description interface'); + } + const imageWithoutDescription: boolean = !image || !image.modal || !image.modal.description || image.modal.description === ''; + const description: string = this.buildTextDescription(image, imageWithoutDescription); + return description; + } + + /** + * Method to reset carousel (force image with index 0 to be the current image and re-init also previews) + */ + // temporary removed because never tested + // reset() { + // if (this.configPlay && this.configPlay.autoPlay) { + // this.stopCarousel(); + // } + // this.currentImage = this.images[0]; + // this.handleBoundaries(0); + // if (this.configPlay && this.configPlay.autoPlay) { + // this.playCarousel(); + // } + // this.ref.markForCheck(); + // } + + /** + * Method to cleanup resources. In fact, this will stop the carousel. + * This is an angular lifecycle hook that is called when this component is destroyed. + */ + ngOnDestroy(): void { + this.stopCarousel(); + } + + /** + * Method to change the current image, receiving the new image as input the relative action. + * @param image an Image object that represents the new image to set as current. + * @param action Enum of type `Action` that represents the source action that triggered the change. + */ + private changeCurrentImage(image: InternalLibImage, action: Action): void { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + this.currentImage = image; + const index: number = getIndex(image, this.images); + + // emit first/last event based on newIndex value + this.emitBoundaryEvent(action, index); + + // emit current visible image index + this.changeImage.emit(new ImageEvent(this.id, action, index + 1)); + } + + /** + * Private method to get the next index. + * This is necessary because at the end, when you call next again, you'll go to the first image. + * That happens because all modal images are shown like in a circle. + */ + private getNextImage(): InternalLibImage { + if (!this.currentImage) { + throw new Error('Internal library error - currentImage must be defined'); + } + const currentIndex: number = getIndex(this.currentImage, this.images); + let newIndex = 0; + if (currentIndex >= 0 && currentIndex < this.images.length - 1) { + newIndex = currentIndex + 1; + } else { + newIndex = 0; // start from the first index + } + return this.images[newIndex] as InternalLibImage; + } + + /** + * Private method to get the previous index. + * This is necessary because at index 0, when you call prev again, you'll go to the last image. + * That happens because all modal images are shown like in a circle. + */ + private getPrevImage(): InternalLibImage { + if (!this.currentImage) { + throw new Error('Internal library error - currentImage must be defined'); + } + const currentIndex: number = getIndex(this.currentImage, this.images); + let newIndex = 0; + if (currentIndex > 0 && currentIndex <= this.images.length - 1) { + newIndex = currentIndex - 1; + } else { + newIndex = this.images.length - 1; // start from the last index + } + return this.images[newIndex] as InternalLibImage; + } + + /** + * Private method to build a text description. + * This is used also to create titles. + * @param Image image to get its description. If not provided it will be the current image. + * @param boolean imageWithoutDescription is a boolean that it's true if the image hasn't a 'modal' description. + * @returns String description built concatenating image fields with a specific logic. + */ + private buildTextDescription(image: Image | undefined, imageWithoutDescription: boolean): string { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig || !libConfig.carouselImageConfig) { + throw new Error('Internal library error - libConfig and carouselImageConfig must be defined'); + } + const configCurrentImageCarousel: CarouselImageConfig | undefined = libConfig.carouselImageConfig; + if (!configCurrentImageCarousel || !configCurrentImageCarousel.description) { + throw new Error('Description input must be a valid object implementing the Description interface'); + } + if (!image) { + throw new Error('Internal library error - image must be defined'); + } + + // If customFullDescription use it, otherwise proceed to build a description + if (configCurrentImageCarousel.description.customFullDescription && configCurrentImageCarousel.description.customFullDescription !== '') { + return configCurrentImageCarousel.description.customFullDescription; + } + + const currentIndex: number = getIndex(image, this.images); + // If the current image hasn't a description, + // prevent to write the ' - ' (or this.description.beforeTextDescription) + + const prevDescription: string = configCurrentImageCarousel.description.imageText ? configCurrentImageCarousel.description.imageText : ''; + const midSeparator: string = configCurrentImageCarousel.description.numberSeparator ? configCurrentImageCarousel.description.numberSeparator : ''; + const middleDescription: string = currentIndex + 1 + midSeparator + this.images.length; + + if (imageWithoutDescription) { + return prevDescription + middleDescription; + } + + const currImgDescription: string = image.modal && image.modal.description ? image.modal.description : ''; + const endDescription: string = configCurrentImageCarousel.description.beforeTextDescription + currImgDescription; + return prevDescription + middleDescription + endDescription; + } + + /** + * Private method to update both `isFirstImage` and `isLastImage` based on + * the index of the current image. + * @param number currentIndex is the index of the current image + */ + private handleBoundaries(currentIndex: number): void { + if (this.images.length === 1) { + this.isFirstImage = true; + this.isLastImage = true; + return; + } + switch (currentIndex) { + case 0: + // execute this only if infinite sliding is disabled + this.isFirstImage = true; + this.isLastImage = false; + break; + case this.images.length - 1: + // execute this only if infinite sliding is disabled + this.isFirstImage = false; + this.isLastImage = true; + break; + default: + this.isFirstImage = false; + this.isLastImage = false; + break; + } + } + + /** + * Private method to manage boundary arrows and sliding. + * This is based on the slideConfig input to enable/disable 'infinite sliding'. + * @param number index of the visible image + */ + private manageSlideConfig(): void { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + if (!this.currentImage) { + throw new Error('Internal library error - currentImage must be defined'); + } + let index: number; + try { + index = getIndex(this.currentImage, this.images); + } catch (err) { + console.error('Cannot get the current image index in current-image'); + throw err; + } + + if (libConfig.carouselSlideInfinite === true) { + // enable infinite sliding + this.isFirstImage = false; + this.isLastImage = false; + } else { + this.handleBoundaries(index); + } + } + + /** + * Private method to emit events when either the last or the first image are visible. + * @param action Enum of type Action that represents the source of the event that changed the + * current image to the first one or the last one. + * @param indexToCheck is the index number of the image (the first or the last one). + */ + private emitBoundaryEvent(action: Action, indexToCheck: number): void { + if (this.id === null || this.id === undefined) { + return; + } + // to emit first/last event + switch (indexToCheck) { + case 0: + this.firstImage.emit(new ImageEvent(this.id, action, true)); + break; + case this.images.length - 1: + this.lastImage.emit(new ImageEvent(this.id, action, true)); + break; + } + } + + /** + * Private method to check if next/prev actions should be blocked. + * It checks if carouselSlideInfinite === false and if the image index is equals to the input parameter. + * If yes, it returns true to say that sliding should be blocked, otherwise not. + * @param number boundaryIndex that could be either the beginning index (0) or the last index + * of images (this.images.length - 1). + * @returns boolean true if carouselSlideInfinite === false and the current index is + * either the first or the last one. + */ + private isPreventSliding(boundaryIndex: number): boolean { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + if (!this.currentImage) { + throw new Error('Internal library error - currentImage must be defined'); + } + return !libConfig.carouselSlideInfinite && getIndex(this.currentImage, this.images) === boundaryIndex; + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel.html b/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel.html new file mode 100644 index 00000000..52d9e045 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel.html @@ -0,0 +1,75 @@ +
+ + + + + +
+ + + + + + + + + + + {{currentImage.modal.alt ? currentImage.modal.alt : getAltDescriptionByImage()}} + +
+ + + + + +
+ +
+ +
+ +
+ + diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel.scss b/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel.scss new file mode 100644 index 00000000..314743b0 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/carousel/carousel.scss @@ -0,0 +1,113 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +$curr-img-margin: 0; +$curr-img-animation-time: .8s; + +$dots-bottom-position: 20px; + +$nav-animation-time: 1s; +$nav-transition-time: .5s; +$nav-side-margin: 15px; +$nav-right-position: 5px; +$nav-left-position: 5px; + +$figcaption-padding: 10px; +$figcaption-position: absolute; +$figcaption-bottom: 0; +$figcaption-left: 0; +$figcaption-right: 0; + +:host { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; +} + +#carousel-container { + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + width: 100%; + + > .current-figure { + animation: fadein-visible $curr-img-animation-time; + text-align: center; + margin: $curr-img-margin; + position: relative; + + .nav { + animation: animatezoom $nav-animation-time; + cursor: pointer; + transition: all $nav-transition-time; + top: 50%; + position: absolute; + + &:hover { + transform: scale(1.1); + } + } + + > .nav-left { + @extend .nav; + left: $nav-left-position; + + } + + > .nav-right { + @extend .nav; + right: $nav-right-position; + } + + > .current-image { + display: block; + > img { + // max width is applied via Angular + width: 100%; + // max-width: 100%; + height: auto; + display: block; + } + } + + > figcaption { + padding: $figcaption-padding; + position: $figcaption-position; + bottom: $figcaption-bottom; + left: $figcaption-left; + right: $figcaption-right; + + & .description { + font-weight: bold; + text-align: center; + } + } + + > #dots { + position: absolute; + bottom: $dots-bottom-position; + width: 100%; + } + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/components.ts b/projects/ks89/angular-modal-gallery/src/lib/components/components.ts new file mode 100644 index 00000000..45cf2c08 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/components.ts @@ -0,0 +1,52 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { CarouselComponent } from './carousel/carousel.component'; +import { CarouselPreviewsComponent } from './carousel/carousel-previews/carousel-previews.component'; +import { UpperButtonsComponent } from './upper-buttons/upper-buttons.component'; +import { DotsComponent } from './dots/dots.component'; +import { PreviewsComponent } from './previews/previews.component'; +import { CurrentImageComponent } from './current-image/current-image.component'; +import { LoadingSpinnerComponent } from './current-image/loading-spinner/loading-spinner.component'; +import { AccessibleComponent } from './accessible.component'; +import { PlainGalleryComponent } from './plain-gallery/plain-gallery.component'; +export { CarouselComponent } from './carousel/carousel.component'; +import { ModalGalleryComponent } from './modal-gallery/modal-gallery.component'; + +/** + * Array of all components. + */ +export const COMPONENTS = [ + PlainGalleryComponent, + CarouselComponent, + CarouselPreviewsComponent, + UpperButtonsComponent, + DotsComponent, + PreviewsComponent, + CurrentImageComponent, + LoadingSpinnerComponent, + AccessibleComponent, + + ModalGalleryComponent +]; diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/current-image/current-image-previews.scss b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/current-image-previews.scss new file mode 100644 index 00000000..aefa0f55 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/current-image-previews.scss @@ -0,0 +1,79 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +$preview-img-normal-opacity: .5; +$preview-img-hover-opacity: 1; + +// Mobile +// Tablet +@media only screen and (max-width: 1024px), only screen and (max-device-width: 1024px) { + .current-image-previous { + display: none; + } + + .current-image-next { + display: none; + } +} + +// Desktops or greater +@media only screen and (min-device-width: 1025px) { + + .current-image-preview { + height: auto; + cursor: pointer; + opacity: $preview-img-normal-opacity; + animation: fadein-semi-visible05 .8s; + filter: alpha(opacity=50); // For IE8 and earlier + + &:hover { + opacity: $preview-img-hover-opacity; + transition-property: opacity; + transition: all .5s ease; + } + } + + .current-image-previous { + @extend .current-image-preview; + margin-left: 10px; + margin-right: 5px; + } + + .current-image-next { + @extend .current-image-preview; + margin-right: 10px; + margin-left: 5px; + } +} + +@mixin fadein($opacity-from, $opacity-to) { + from { + opacity: $opacity-from; + } + to { + opacity: $opacity-to; + } +} + +@keyframes fadein-semi-visible05 { + @include fadein(0, .5); +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/current-image/current-image.component.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/current-image.component.spec.ts new file mode 100644 index 00000000..6f1f2270 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/current-image.component.spec.ts @@ -0,0 +1,1332 @@ +/* + * Copyright (C) 2017-2024 Stefano Cappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentFixture, discardPeriodicTasks, fakeAsync, flush, TestBed, tick } from '@angular/core/testing'; +import { DebugElement, SimpleChanges } from '@angular/core'; +import { By, SafeResourceUrl } from '@angular/platform-browser'; +import { KS_DEFAULT_ACCESSIBILITY_CONFIG } from '../accessibility-default'; +import { InternalLibImage } from '../../model/image-internal.class'; +import { CurrentImageComponent } from './current-image.component'; +import { SizeDirective } from '../../directives/size.directive'; +import { LoadingSpinnerComponent } from './loading-spinner/loading-spinner.component'; +import { KeyboardNavigationDirective } from '../../directives/keyboard-navigation.directive'; +import { LoadingConfig, LoadingType } from '../../model/loading-config.interface'; +import { SlideConfig } from '../../model/slide-config.interface'; +import { Description, DescriptionStrategy } from '../../model/description.interface'; +import { Size } from '../../model/size.interface'; +import { AccessibilityConfig } from '../../model/accessibility.interface'; +import { ImageModalEvent } from '../../model/image.class'; +import { Action } from '../../model/action.enum'; +import { DescriptionDirective } from '../../directives/description.directive'; +import { ConfigService } from '../../services/config.service'; +import { FallbackImageDirective } from '../../directives/fallback-image.directive'; + +let comp: CurrentImageComponent; +let fixture: ComponentFixture; + +interface TestModel { + currentImgTitle: string; + currentAlt: string; + currentDescription: string; + leftPreviewTitle: string; + leftPreviewAlt: string; + rightPreviewTitle: string; + rightPreviewAlt: string; +} + +const TEST_MODEL: TestModel[] = [ + { + currentImgTitle: 'Image 1/5', + currentAlt: 'Image 1', + currentDescription: 'Image 1/5', + leftPreviewTitle: '', + leftPreviewAlt: '', + rightPreviewTitle: 'Image 2/5 - Description 2', + rightPreviewAlt: 'Description 2' + }, + { + currentImgTitle: 'Image 2/5 - Description 2', + currentAlt: 'Description 2', + currentDescription: 'Image 2/5 - Description 2', + leftPreviewTitle: 'Image 1/5', + leftPreviewAlt: 'Image 1', + rightPreviewTitle: 'Image 3/5 - Description 3', + rightPreviewAlt: 'Description 3' + }, + { + currentImgTitle: 'Image 3/5 - Description 3', + currentAlt: 'Description 3', + currentDescription: 'Image 3/5 - Description 3', + leftPreviewTitle: 'Image 2/5 - Description 2', + leftPreviewAlt: 'Description 2', + rightPreviewTitle: 'Image 4/5 - Description 4', + rightPreviewAlt: 'Description 4' + }, + { + currentImgTitle: 'Image 4/5 - Description 4', + currentAlt: 'Description 4', + currentDescription: 'Image 4/5 - Description 4', + leftPreviewTitle: 'Image 3/5 - Description 3', + leftPreviewAlt: 'Description 3', + rightPreviewTitle: 'Image 5/5', + rightPreviewAlt: 'Image 5' + }, + { + currentImgTitle: 'Image 5/5', + currentAlt: 'Image 5', + currentDescription: 'Image 5/5', + leftPreviewTitle: 'Image 4/5 - Description 4', + leftPreviewAlt: 'Description 4', + rightPreviewTitle: '', + rightPreviewAlt: '' + } +]; + +const TEST_MODEL_SINGLE_IMAGE: TestModel = TEST_MODEL[0]; + +const TEST_MODEL_INFINITE: TestModel[] = [ + { + currentImgTitle: 'Image 1/5', + currentAlt: 'Image 1', + currentDescription: 'Image 1/5', + leftPreviewTitle: 'Image 5/5', + leftPreviewAlt: 'Image 5', + rightPreviewTitle: 'Image 2/5 - Description 2', + rightPreviewAlt: 'Description 2' + }, + { + currentImgTitle: 'Image 2/5 - Description 2', + currentAlt: 'Description 2', + currentDescription: 'Image 2/5 - Description 2', + leftPreviewTitle: 'Image 1/5', + leftPreviewAlt: 'Image 1', + rightPreviewTitle: 'Image 3/5 - Description 3', + rightPreviewAlt: 'Description 3' + }, + { + currentImgTitle: 'Image 3/5 - Description 3', + currentAlt: 'Description 3', + currentDescription: 'Image 3/5 - Description 3', + leftPreviewTitle: 'Image 2/5 - Description 2', + leftPreviewAlt: 'Description 2', + rightPreviewTitle: 'Image 4/5 - Description 4', + rightPreviewAlt: 'Description 4' + }, + { + currentImgTitle: 'Image 4/5 - Description 4', + currentAlt: 'Description 4', + currentDescription: 'Image 4/5 - Description 4', + leftPreviewTitle: 'Image 3/5 - Description 3', + leftPreviewAlt: 'Description 3', + rightPreviewTitle: 'Image 5/5', + rightPreviewAlt: 'Image 5' + }, + { + currentImgTitle: 'Image 5/5', + currentAlt: 'Image 5', + currentDescription: 'Image 5/5', + leftPreviewTitle: 'Image 4/5 - Description 4', + leftPreviewAlt: 'Description 4', + rightPreviewTitle: 'Image 1/5', + rightPreviewAlt: 'Image 1' + } +]; + +const TEST_MODEL_ALWAYSEMPTY_DESCRIPTIONS: TestModel[] = [ + Object.assign({}, TEST_MODEL[0], {leftPreviewTitle: '', rightPreviewTitle: ''}), + Object.assign({}, TEST_MODEL[1], {leftPreviewTitle: '', rightPreviewTitle: ''}), + Object.assign({}, TEST_MODEL[2], {leftPreviewTitle: '', rightPreviewTitle: ''}), + Object.assign({}, TEST_MODEL[3], {leftPreviewTitle: '', rightPreviewTitle: ''}), + Object.assign({}, TEST_MODEL[4], {leftPreviewTitle: '', rightPreviewTitle: ''}) +]; + +const TEST_MODEL_HIDEEMPTY_DESCRIPTIONS: TestModel[] = [ + Object.assign({}, TEST_MODEL[0], { + currentImgTitle: 'Image 1/5', leftPreviewTitle: '', + rightPreviewTitle: 'Image 2/5 - Description 2', currentDescription: 'Image 1/5' + }), + Object.assign({}, TEST_MODEL[1], { + currentImgTitle: 'Image 2/5 - Description 2', leftPreviewTitle: 'Image 1/5', + rightPreviewTitle: 'Image 3/5 - Description 3', currentDescription: 'Description 2' + }), + Object.assign({}, TEST_MODEL[2], { + currentImgTitle: 'Image 3/5 - Description 3', leftPreviewTitle: 'Image 2/5 - Description 2', + rightPreviewTitle: 'Image 4/5 - Description 4', currentDescription: 'Description 3' + }), + Object.assign({}, TEST_MODEL[3], { + currentImgTitle: 'Image 4/5 - Description 4', leftPreviewTitle: 'Image 3/5 - Description 3', + rightPreviewTitle: 'Image 5/5', currentDescription: 'Description 4' + }), + Object.assign({}, TEST_MODEL[4], { + currentImgTitle: 'Image 5/5', leftPreviewTitle: 'Image 4/5 - Description 4', + rightPreviewTitle: '', currentDescription: 'Image 5/5' + }) +]; + +const CUSTOM_ACCESSIBILITY: AccessibilityConfig = Object.assign({}, KS_DEFAULT_ACCESSIBILITY_CONFIG); +CUSTOM_ACCESSIBILITY.mainContainerTitle = 'custom mainContainerTitle'; +CUSTOM_ACCESSIBILITY.mainContainerAriaLabel = 'custom mainContainerAriaLabel'; +CUSTOM_ACCESSIBILITY.mainNextImageTitle = 'custom mainNextImageTitle'; +CUSTOM_ACCESSIBILITY.mainNextImageAriaLabel = 'custom mainNextImageAriaLabel'; +CUSTOM_ACCESSIBILITY.mainPrevImageTitle = 'custom mainPrevImageTitle'; +CUSTOM_ACCESSIBILITY.mainPrevImageAriaLabel = 'custom mainPrevImageAriaLabel'; + +const DEFAULT_SIZE: Size = {height: 'auto', width: '100px'}; +const CUSTOM_SIZE: Size = {height: '100px', width: '100px'}; +const CUSTOM_SIZE_AUTO_HEIGHT: Size = {height: 'auto', width: '100px'}; +const CUSTOM_SIZE_AUTO_WIDTH: Size = {height: '100px', width: 'auto'}; +const CUSTOM_SIZES: Size[] = [CUSTOM_SIZE, CUSTOM_SIZE_AUTO_HEIGHT, CUSTOM_SIZE_AUTO_WIDTH]; + +const CUSTOM_SLIDE_CONFIG: SlideConfig[] = [ + {infinite: false, sidePreviews: {show: true, size: CUSTOM_SIZE}}, + {infinite: false, sidePreviews: {show: true, size: CUSTOM_SIZE_AUTO_HEIGHT}}, + {infinite: false, sidePreviews: {show: true, size: CUSTOM_SIZE_AUTO_WIDTH}}, + {sidePreviews: {show: true, size: DEFAULT_SIZE}} +]; + +const CUSTOM_SLIDE_CONFIG_INFINITE: SlideConfig[] = [ + {infinite: true, sidePreviews: {show: true, size: DEFAULT_SIZE}}, + {infinite: true, sidePreviews: {show: true, size: DEFAULT_SIZE}}, + {infinite: true, sidePreviews: {show: true, size: DEFAULT_SIZE}}, + {infinite: true} +]; + +const GALLERY_ID = 1; + +const IMAGES: InternalLibImage[] = [ + new InternalLibImage(0, { + // modal + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new InternalLibImage(1, { + // modal + img: '../assets/images/gallery/img2.png', + description: 'Description 2' + }), + new InternalLibImage( + 2, + { + // modal + img: '../assets/images/gallery/img3.jpg', + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + // plain + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new InternalLibImage(3, { + // modal + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new InternalLibImage( + 4, + { + // modal + img: '../assets/images/gallery/img5.jpg' + }, + { + // plain + img: '../assets/images/gallery/thumbs/img5.jpg' + } + ) +]; + +const IMAGES_BASE64: InternalLibImage[] = [ + new InternalLibImage(0, { + // modal + img: 'data:image/png;base64,iVBORw0KG=' as SafeResourceUrl, + extUrl: 'http://www.google.com' + }), + new InternalLibImage(1, { + // modal + img: 'data:image/png;base64,iVBORw0KG=' as SafeResourceUrl, + description: 'Description 2' + }), + new InternalLibImage( + 2, + { + // modal + img: 'data:image/png;base64,iVBORw0KG=' as SafeResourceUrl, + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + // plain + img: 'data:image/png;base64,iVBORw0KG=' as SafeResourceUrl, + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new InternalLibImage(3, { + // modal + img: 'data:image/png;base64,iVBORw0KG=' as SafeResourceUrl, + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new InternalLibImage( + 4, + { + // modal + img: 'data:image/png;base64,iVBORw0KG=' as SafeResourceUrl + }, + { + // plain + img: 'data:image/png;base64,iVBORw0KG=' as SafeResourceUrl + } + ) +]; + +function checkMainContainer(): void { + const element: DebugElement = fixture.debugElement; + const mainCurrentImage: DebugElement = element.query(By.css('main.main-image-container')); + expect(mainCurrentImage.name).toBe('main'); + expect(mainCurrentImage.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.mainContainerTitle); + expect(mainCurrentImage.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.mainContainerAriaLabel); +} + +function checkCurrentImage(currentImage: InternalLibImage, val: TestModel, withDescription: boolean = true): void { + const element: DebugElement = fixture.debugElement; + const currentFigure: DebugElement = element.query(By.css('figure#current-figure')); + expect(currentFigure.name).toBe('figure'); + const currentPictureElement: DebugElement = currentFigure.children[0]; + expect(currentPictureElement.name).toBe('picture'); + const currentImageElement: DebugElement = currentPictureElement.children[0]; + expect(currentImageElement.name).toBe('img'); + expect(currentImageElement.attributes.class).toBe('inside'); + expect(currentImageElement.attributes.role).toBe('img'); + expect(currentImageElement.properties.src).toBe(currentImage.modal.img); + expect(currentImageElement.properties.title).toBe(val.currentImgTitle); + expect(currentImageElement.properties.alt).toBe(val.currentAlt); + expect(currentImageElement.properties.tabIndex).toBe(0); + + if (withDescription) { + const currentFigcaption: DebugElement = currentFigure.children[1]; + expect(containsClasses(currentFigcaption.attributes.class as string, 'description inside')).toBeTrue(); + expect(currentFigcaption.nativeElement.textContent).toEqual(val.currentDescription); + } +} + +function checkArrows(isFirstImage: boolean, isLastImage: boolean): void { + const element: DebugElement = fixture.debugElement; + const aNavLeft: DebugElement = element.query(By.css('a.nav-left')); + expect(aNavLeft.name).toBe('a'); + expect(aNavLeft.attributes.role).toBe('button'); + expect(aNavLeft.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.mainPrevImageAriaLabel); + // expect(aNavLeft.properties.tabIndex).toBe(isFirstImage ? -1 : 0); + const divNavLeft: DebugElement = aNavLeft.children[0]; + expect(divNavLeft.attributes['aria-hidden']).toBe('true'); + expect(containsClasses(divNavLeft.properties.className as string, (isFirstImage ? 'empty-arrow-image' : 'left-arrow-image') + ' inside')).toBeTrue(); + expect(divNavLeft.properties.title).toBe(isFirstImage ? '' : KS_DEFAULT_ACCESSIBILITY_CONFIG.mainPrevImageTitle); + + const aNavRight: DebugElement = element.query(By.css('a.nav-right')); + expect(aNavRight.name).toBe('a'); + expect(aNavRight.attributes.role).toBe('button'); + expect(aNavRight.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.mainNextImageAriaLabel); + // expect(aNavRight.properties.tabIndex).toBe(isLastImage ? -1 : 0); + const divNavRight: DebugElement = aNavRight.children[0]; + expect(divNavRight.attributes['aria-hidden']).toBe('true'); + expect(containsClasses(divNavRight.properties.className as string, (isLastImage ? 'empty-arrow-image' : 'right-arrow-image') + ' inside')).toBeTrue(); + expect(divNavRight.properties.title).toBe(isLastImage ? '' : KS_DEFAULT_ACCESSIBILITY_CONFIG.mainNextImageTitle); +} + +function checkSidePreviews(prevImage: InternalLibImage, nextImage: InternalLibImage, + isFirstImage: boolean, isLastImage: boolean, val: TestModel, size: Size = DEFAULT_SIZE): void { + const element: DebugElement = fixture.debugElement; + const leftPreviewImage: DebugElement = element.query(By.css(isFirstImage + ? 'div.current-image-previous.hidden' + : 'img.inside.current-image-previous')); + expect(leftPreviewImage.name).toBe(isFirstImage ? 'div' : 'img'); + if (!isFirstImage) { + expect(leftPreviewImage.properties.src).toBe(prevImage.plain ? prevImage.plain.img : prevImage.modal.img); + expect(leftPreviewImage.properties.title).toBe(val.leftPreviewTitle); + expect(leftPreviewImage.properties.alt).toBe(val.leftPreviewAlt); + } + expect(leftPreviewImage.attributes.class).toBe(isFirstImage ? 'current-image-previous hidden' : 'inside current-image-previous'); + expect(leftPreviewImage.styles.width).toBe(size.width); + expect(leftPreviewImage.styles.height).toBe(size.height); + + const rightPreviewImage: DebugElement = element.query(By.css(isLastImage + ? 'div.current-image-next.hidden' + : 'img.inside.current-image-next')); + expect(rightPreviewImage.name).toBe(isLastImage ? 'div' : 'img'); + if (!isLastImage) { + expect(rightPreviewImage.properties.src).toBe(nextImage.plain ? nextImage.plain.img : nextImage.modal.img); + expect(rightPreviewImage.properties.title).toBe(val.rightPreviewTitle); + expect(rightPreviewImage.properties.alt).toBe(val.rightPreviewAlt); + } + expect(rightPreviewImage.attributes.class).toBe(isLastImage ? 'current-image-next hidden' : 'inside current-image-next'); + expect(rightPreviewImage.styles.width).toBe(size.width); + expect(rightPreviewImage.styles.height).toBe(size.height); +} + +function containsClasses(actualClasses: string, expectedClasses: string): boolean { + const actual: string[] = actualClasses.split(' '); + const expected: string[] = expectedClasses.split(' '); + let count = 0; + if (actual.length !== expected.length) { + return false; + } + expected.forEach((item: string) => { + if (actual.includes(item)) { + count++; + } + }); + return count === expected.length; +} + +function initTestBed(): void { + TestBed.configureTestingModule({ + declarations: [CurrentImageComponent, LoadingSpinnerComponent, KeyboardNavigationDirective, DescriptionDirective, SizeDirective, FallbackImageDirective] + }).overrideComponent(CurrentImageComponent, { + set: { + providers: [ + { + provide: ConfigService, + useClass: ConfigService + } + ] + } + }); +} + +describe('CurrentImageComponent', () => { + beforeEach(() => { + initTestBed(); + fixture = TestBed.createComponent(CurrentImageComponent); + comp = fixture.componentInstance; + }); + + it('should instantiate it', () => expect(comp).not.toBeNull()); + + describe('---YES---', () => { + + TEST_MODEL.forEach((val: TestModel, index: number) => { + it(`should display current image with arrows and side previews. Test i=${index}`, () => { + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[index]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + }, + slideConfig: {infinite: false, sidePreviews: {show: true, size: DEFAULT_SIZE}} as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[index], val); + }); + }); + + TEST_MODEL.forEach((val: TestModel, index: number) => { + it(`should display current image as base64 with arrows and side previews. Test i=${index}`, () => { + comp.id = GALLERY_ID; + comp.images = IMAGES_BASE64; + comp.currentImage = IMAGES_BASE64[index]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + }, + slideConfig: {infinite: false, sidePreviews: {show: true, size: DEFAULT_SIZE}} as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES_BASE64[index], val); + }); + }); + + it(`should display current image with arrows and side previews when there is only one image.`, () => { + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + }, + slideConfig: {infinite: false, sidePreviews: {show: true, size: DEFAULT_SIZE}} as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[0], TEST_MODEL_SINGLE_IMAGE); + }); + + TEST_MODEL.forEach((val: TestModel, index: number) => { + it(`should navigate between images clicking on current image. Test i=${index}`, () => { + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[index]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + }, + slideConfig: {infinite: false, sidePreviews: {show: true, size: DEFAULT_SIZE}} as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[index], val); + checkArrows(index === 0, index === IMAGES.length - 1); + checkSidePreviews(IMAGES[index - 1], IMAGES[index + 1], index === 0, index === IMAGES.length - 1, val); + + const element: DebugElement = fixture.debugElement; + const currentImage: DebugElement = element.query(By.css('picture.current-image>img')); + expect(currentImage.name).toBe('img'); + + if (index !== IMAGES.length - 1) { + comp.changeImage.subscribe((res: ImageModalEvent) => { + expect(res.result).toBe(index + 1); + expect(res.action).toBe(Action.CLICK); + }); + + currentImage.nativeElement.click(); + } + }); + }); + + TEST_MODEL.forEach((val: TestModel, index: number) => { + it(`should navigate between images clicking on right side preview. Test i=${index}`, () => { + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[index]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + }, + slideConfig: {infinite: false, sidePreviews: {show: true, size: DEFAULT_SIZE}} as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[index], val); + checkArrows(index === 0, index === IMAGES.length - 1); + checkSidePreviews(IMAGES[index - 1], IMAGES[index + 1], index === 0, index === IMAGES.length - 1, val); + + const element: DebugElement = fixture.debugElement; + const rightPreviewImage: DebugElement = element.query(By.css(index === IMAGES.length - 1 + ? 'div.current-image-next.hidden' + : 'img.inside.current-image-next')); + + if (index !== IMAGES.length - 1) { + comp.changeImage.subscribe((res: ImageModalEvent) => { + expect(res.result).toBe(index + 1); + expect(res.action).toBe(Action.CLICK); + }); + + spyOn(comp, 'onNavigationEvent').and.callThrough(); + + rightPreviewImage.nativeElement.click(); + } + }); + }); + + [...TEST_MODEL].reverse().forEach((val: TestModel, index: number) => { + it(`should navigate between images clicking on left side preview. Test i=${index}`, () => { + const currentIndex: number = IMAGES.length - 1 - index; + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[currentIndex]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + }, + slideConfig: {infinite: false, sidePreviews: {show: true, size: DEFAULT_SIZE}} as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[currentIndex], val); + checkArrows(currentIndex === 0, currentIndex === IMAGES.length - 1); + checkSidePreviews(IMAGES[currentIndex - 1], IMAGES[currentIndex + 1], currentIndex === 0, currentIndex === IMAGES.length - 1, val); + + const element: DebugElement = fixture.debugElement; + const leftPreviewImage: DebugElement = element.query(By.css(currentIndex === 0 + ? 'div.current-image-previous.hidden' + : 'img.inside.current-image-previous')); + + if (currentIndex !== 0) { + comp.changeImage.subscribe((res: ImageModalEvent) => { + expect(res.result).toBe(currentIndex - 1); + expect(res.action).toBe(Action.CLICK); + }); + + spyOn(comp, 'onNavigationEvent').and.callThrough(); + + leftPreviewImage.nativeElement.click(); + } + }); + }); + + TEST_MODEL.forEach((val: TestModel, index: number) => { + it(`should navigate between images to the right using swipe gestures. Test i=${index}`, () => { + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[index]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + }, + slideConfig: {infinite: false, sidePreviews: {show: true, size: DEFAULT_SIZE}} as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[index], val); + checkArrows(index === 0, index === IMAGES.length - 1); + checkSidePreviews(IMAGES[index - 1], IMAGES[index + 1], index === 0, index === IMAGES.length - 1, val); + + if (index !== IMAGES.length - 1) { + comp.changeImage.subscribe((res: ImageModalEvent) => { + expect(res.result).toBe(index + 1); + expect(res.action).toBe(Action.SWIPE); + }); + + spyOn(comp, 'onNavigationEvent').and.callThrough(); + + comp.swipe('swiperight'); + } + }); + }); + + [...TEST_MODEL].reverse().forEach((val: TestModel, index: number) => { + it(`should navigate between images to the left using swipe gestures. Test i=${index}`, () => { + const currentIndex: number = IMAGES.length - 1 - index; + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[currentIndex]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + }, + slideConfig: {infinite: false, sidePreviews: {show: true, size: DEFAULT_SIZE}} as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[currentIndex], val); + checkArrows(currentIndex === 0, currentIndex === IMAGES.length - 1); + checkSidePreviews(IMAGES[currentIndex - 1], IMAGES[currentIndex + 1], currentIndex === 0, currentIndex === IMAGES.length - 1, val); + + if (currentIndex !== 0) { + comp.changeImage.subscribe((res: ImageModalEvent) => { + expect(res.result).toBe(currentIndex - 1); + expect(res.action).toBe(Action.SWIPE); + }); + + spyOn(comp, 'onNavigationEvent').and.callThrough(); + + comp.swipe('swipeleft'); + } + }); + }); + + TEST_MODEL.forEach((val: TestModel, index: number) => { + it(`should invert swipe navigation with the 'invertSwipe' property to true navigating to the left. Test i=${index}`, () => { + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[index]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description, + invertSwipe: true + }, + slideConfig: {infinite: false, sidePreviews: {show: true, size: DEFAULT_SIZE}} as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[index], val); + checkArrows(index === 0, index === IMAGES.length - 1); + checkSidePreviews(IMAGES[index - 1], IMAGES[index + 1], index === 0, index === IMAGES.length - 1, val); + + if (index !== IMAGES.length - 1) { + comp.changeImage.subscribe((res: ImageModalEvent) => { + expect(res.result).toBe(index + 1); + expect(res.action).toBe(Action.SWIPE); + }); + + spyOn(comp, 'onNavigationEvent').and.callThrough(); + + comp.swipe('swipeleft'); + } + }); + }); + + [...TEST_MODEL].reverse().forEach((val: TestModel, index: number) => { + it(`should invert swipe navigation with the 'invertSwipe' property to true navigating to the right. Test i=${index}`, () => { + const currentIndex: number = IMAGES.length - 1 - index; + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[currentIndex]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description, + invertSwipe: true + }, + slideConfig: {infinite: false, sidePreviews: {show: true, size: DEFAULT_SIZE}} as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[currentIndex], val); + checkArrows(currentIndex === 0, currentIndex === IMAGES.length - 1); + checkSidePreviews(IMAGES[currentIndex - 1], IMAGES[currentIndex + 1], currentIndex === 0, currentIndex === IMAGES.length - 1, val); + + if (currentIndex !== 0) { + comp.changeImage.subscribe((res: ImageModalEvent) => { + expect(res.result).toBe(currentIndex - 1); + expect(res.action).toBe(Action.SWIPE); + }); + + spyOn(comp, 'onNavigationEvent').and.callThrough(); + + comp.swipe('swiperight'); + } + }); + }); + + TEST_MODEL_ALWAYSEMPTY_DESCRIPTIONS.forEach((val: TestModel, index: number) => { + it(`should display current image when description is ALWAYS_HIDDEN. Test i=${index}`, () => { + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[index]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_HIDDEN} as Description + }, + slideConfig: {infinite: false, sidePreviews: {show: true, size: DEFAULT_SIZE}} as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[index], val, false); + checkArrows(index === 0, index === IMAGES.length - 1); + checkSidePreviews(IMAGES[index - 1], IMAGES[index + 1], index === 0, index === IMAGES.length - 1, val); + }); + }); + + TEST_MODEL_HIDEEMPTY_DESCRIPTIONS.forEach((val: TestModel, index: number) => { + it(`should display current image when description is HIDE_IF_EMPTY. Test i=${index}`, () => { + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[index]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.HIDE_IF_EMPTY} as Description + }, + slideConfig: {infinite: false, sidePreviews: {show: true, size: DEFAULT_SIZE}} as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + const imageWithoutDescription: boolean = !IMAGES[index].modal || !IMAGES[index].modal.description || IMAGES[index].modal.description === ''; + // TODO fixme + // checkCurrentImage(IMAGES[index], val, !imageWithoutDescription); + // checkArrows(index === 0, index === IMAGES.length - 1); + // checkSidePreviews(IMAGES[index - 1], IMAGES[index + 1], index === 0, index === IMAGES.length - 1, val); + }); + }); + + CUSTOM_SLIDE_CONFIG.forEach((slideConfig: SlideConfig, j: number) => { + TEST_MODEL.forEach((val: TestModel, index: number) => { + it(`should display current image, arrows and side previews with custom slideConfig. Test i=${index}, j=${j}`, () => { + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[index]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + }, + slideConfig: slideConfig as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[index], val); + checkArrows(index === 0, index === IMAGES.length - 1); + checkSidePreviews(IMAGES[index - 1], IMAGES[index + 1], + index === 0, index === IMAGES.length - 1, + val, slideConfig.sidePreviews ? slideConfig.sidePreviews.size : DEFAULT_SIZE); + }); + }); + }); + + CUSTOM_SLIDE_CONFIG_INFINITE.forEach((slideConfig: SlideConfig, j: number) => { + TEST_MODEL_INFINITE.forEach((val: TestModel, index: number) => { + it(`should display current image, arrows and side previews with infinite sliding. Test i=${index}, j=${j}`, () => { + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[index]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + }, + slideConfig: slideConfig as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[index], val); + checkArrows((index === 0) && !slideConfig.infinite, (index === IMAGES.length - 1) && !slideConfig.infinite); + if (slideConfig.sidePreviews) { + checkSidePreviews( + index === 0 ? IMAGES[IMAGES.length - 1] : IMAGES[index - 1], + index === IMAGES.length - 1 ? IMAGES[0] : IMAGES[index + 1], + (index === 0) && !slideConfig.infinite, (index === IMAGES.length - 1) && !slideConfig.infinite, + val, slideConfig.sidePreviews ? slideConfig.sidePreviews.size : DEFAULT_SIZE); + } + }); + }); + }); + + TEST_MODEL_INFINITE.forEach((val: TestModel, index: number) => { + it(`should display current image and arrows WITHOUT side previews and with infinite sliding ENBALED. Test i=${index}.`, () => { + comp.id = GALLERY_ID; + const images = IMAGES; + comp.images = images; + comp.currentImage = images[index]; + comp.isOpen = true; + + const slideConfig: SlideConfig = { + infinite: true, + sidePreviews: { + show: false, + size: DEFAULT_SIZE + } + }; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + }, + slideConfig: slideConfig as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + checkCurrentImage(images[index], val); + + // infinite sliding enabled, so first and last are always false + const isFirstImage = false; + const isLastImage = false; + + checkArrows(isFirstImage, isLastImage); + + const element: DebugElement = fixture.debugElement; + const aNavLeft: DebugElement = element.query(By.css('a.nav-left')); + expect(aNavLeft.name).toBe('a'); + expect(aNavLeft.attributes.role).toBe('button'); + expect(aNavLeft.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.mainPrevImageAriaLabel); + expect(aNavLeft.properties.tabIndex).toBe(isFirstImage ? -1 : 0); + const divNavLeft: DebugElement = aNavLeft.children[0]; + expect(divNavLeft.attributes['aria-hidden']).toBe('true'); + expect(containsClasses(divNavLeft.properties.className as string, (isFirstImage ? 'empty-arrow-image' : 'left-arrow-image') + ' inside')).toBeTrue(); + expect(divNavLeft.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.mainPrevImageTitle); + + const aNavRight: DebugElement = element.query(By.css('a.nav-right')); + expect(aNavRight.name).toBe('a'); + expect(aNavRight.attributes.role).toBe('button'); + expect(aNavRight.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.mainNextImageAriaLabel); + expect(aNavRight.properties.tabIndex).toBe(isLastImage ? -1 : 0); + const divNavRight: DebugElement = aNavRight.children[0]; + expect(divNavRight.attributes['aria-hidden']).toBe('true'); + expect(containsClasses(divNavRight.properties.className as string, (isLastImage ? 'empty-arrow-image' : 'right-arrow-image') + ' inside')).toBeTrue(); + expect(divNavRight.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.mainNextImageTitle); + + // no side previews + const leftPreviewImage: DebugElement = element.query(By.css('img.inside.current-image-previous')); + expect(leftPreviewImage).toBeNull(); + const rightPreviewImage: DebugElement = element.query(By.css('img.inside.current-image-next')); + expect(rightPreviewImage).toBeNull(); + }); + }); + + // FIXME not working for first and last images + // TEST_MODEL.forEach((val: TestModel, index: number) => { + // it(`should display current image and arrows WITHOUT side previews and with infinite sliding DISABLED. Test i=${index}.`, () => { + // comp.id = GALLERY_ID; + // const images = IMAGES; + // comp.images = images; + // comp.currentImage = images[index]; + // comp.isOpen = true; + // + // const slideConfig: SlideConfig = { + // infinite: false, + // sidePreviews: { + // show: false, + // size: DEFAULT_SIZE + // } + // }; + // + // const configService = fixture.debugElement.injector.get(ConfigService); + // configService.setConfig(GALLERY_ID, { + // currentImageConfig: { + // loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + // description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + // }, + // slideConfig: slideConfig as SlideConfig, + // accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + // }); + // + // fixture.detectChanges(); + // + // // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // // isFirstImage and isLastImage in template file. + // // Taken from https://stackoverflow.com/a/52214200/3590376 + // comp.ref.detectChanges(); + // + // checkMainContainer(); + // checkCurrentImage(images[index], val); + // + // // infinite sliding disabled, so first and last images are based on current image index + // let isFirstImage: boolean; + // let isLastImage: boolean; + // switch (index) { + // case 0: + // isFirstImage = true; + // isLastImage = false; + // break; + // case images.length - 1: + // isFirstImage = false; + // isLastImage = true; + // break; + // default: + // isFirstImage = false; + // isLastImage = false; + // break; + // } + // + // checkArrows(isFirstImage, isLastImage); + // + // const element: DebugElement = fixture.debugElement; + // const aNavLeft: DebugElement = element.query(By.css('a.nav-left')); + // expect(aNavLeft.name).toBe('a'); + // expect(aNavLeft.attributes.role).toBe('button'); + // expect(aNavLeft.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.mainPrevImageAriaLabel); + // expect(aNavLeft.properties.tabIndex).toBe(isFirstImage ? -1 : 0); + // const divNavLeft: DebugElement = aNavLeft.children[0]; + // expect(divNavLeft.attributes['aria-hidden']).toBe('true'); + // expect(containsClasses(divNavLeft.properties.className as string, (isFirstImage ? 'empty-arrow-image' : 'left-arrow-image') + ' inside')).toBeTrue(); + // expect(divNavLeft.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.mainPrevImageTitle); + // + // const aNavRight: DebugElement = element.query(By.css('a.nav-right')); + // expect(aNavRight.name).toBe('a'); + // expect(aNavRight.attributes.role).toBe('button'); + // expect(aNavRight.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.mainNextImageAriaLabel); + // expect(aNavRight.properties.tabIndex).toBe(isLastImage ? -1 : 0); + // const divNavRight: DebugElement = aNavRight.children[0]; + // expect(divNavRight.attributes['aria-hidden']).toBe('true'); + // expect(containsClasses(divNavRight.properties.className as string, (isLastImage ? 'empty-arrow-image' : 'right-arrow-image') + ' inside')).toBeTrue(); + // expect(divNavRight.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.mainNextImageTitle); + // + // // no side previews + // const leftPreviewImage: DebugElement = element.query(By.css('img.current-image-previous.hidden')); + // expect(leftPreviewImage).toBeNull(); + // const rightPreviewImage: DebugElement = element.query(By.css('img.current-image-next.hidden')); + // expect(rightPreviewImage).toBeNull(); + // }); + // }); + + IMAGES.forEach((image: InternalLibImage, index: number) => { + it(`should display current image with custom accessibility. Image with index = ${index}.`, () => { + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[index]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + }, + slideConfig: {infinite: false, sidePreviews: {show: true, size: DEFAULT_SIZE}} as SlideConfig, + accessibilityConfig: CUSTOM_ACCESSIBILITY + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + const element: DebugElement = fixture.debugElement; + const mainCurrentImage: DebugElement = element.query(By.css('main.main-image-container')); + expect(mainCurrentImage.properties.title).toBe(CUSTOM_ACCESSIBILITY.mainContainerTitle); + expect(mainCurrentImage.attributes['aria-label']).toBe(CUSTOM_ACCESSIBILITY.mainContainerAriaLabel); + + const aNavLeft: DebugElement = element.query(By.css('a.nav-left')); + expect(aNavLeft.attributes['aria-label']).toBe(CUSTOM_ACCESSIBILITY.mainPrevImageAriaLabel); + if (index === 0) { + // is either first or last image + expect(aNavLeft.children[0].properties.title).toBe(''); + } else { + expect(aNavLeft.children[0].properties.title).toBe(CUSTOM_ACCESSIBILITY.mainPrevImageTitle); + } + + const aNavRight: DebugElement = element.query(By.css('a.nav-right')); + expect(aNavRight.attributes['aria-label']).toBe(CUSTOM_ACCESSIBILITY.mainNextImageAriaLabel); + if (index === IMAGES.length - 1) { + // is either first or last image + expect(aNavRight.children[0].properties.title).toBe(''); + } else { + expect(aNavRight.children[0].properties.title).toBe(CUSTOM_ACCESSIBILITY.mainNextImageTitle); + } + }); + }); + + it(`should display current image with an array of images with a single element.`, () => { + comp.id = GALLERY_ID; + comp.images = [IMAGES[0]]; + comp.currentImage = IMAGES[0]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + }, + slideConfig: {infinite: false, sidePreviews: {show: true, size: DEFAULT_SIZE}} as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + const model: TestModel = { + currentImgTitle: 'Image 1/1', + currentAlt: 'Image 1', + currentDescription: 'Image 1/1', + leftPreviewTitle: '', + leftPreviewAlt: '', + rightPreviewTitle: '', + rightPreviewAlt: '' + }; + checkCurrentImage(IMAGES[0], model); + }); + + it(`should display gallery with all defaults and auto-navigate (play enabled).`, fakeAsync(() => { + comp.id = 0; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + }, + slideConfig: {playConfig: {autoPlay: true, interval: 5000, pauseOnHover: true}} as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + const defaultInterval = 5000; + + comp.isFirstImage = true; + comp.isLastImage = false; + + TEST_MODEL.forEach((val: TestModel, index: number) => { + checkMainContainer(); + // TODO FIX THIS!!!! + checkCurrentImage(IMAGES[index], val); + // checkArrows(index === 0, index === IMAGES.length - 1); + tick(defaultInterval + 100); + if (index < IMAGES.length - 1) { + comp.currentImage = IMAGES[index + 1]; + comp.ngOnChanges({ + currentImage: { + previousValue: IMAGES[index], + currentValue: IMAGES[index + 1], + firstChange: false, + isFirstChange: () => false + } + } as SimpleChanges); + } + flush(); + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + }); + + tick(defaultInterval + 100); + flush(); + fixture.detectChanges(); + + discardPeriodicTasks(); + })); + }); + + describe('---NO---', () => { + it(`cannot navigate from the last image to the first one if infinite sliding is disabled`, () => { + const index: number = IMAGES.length - 1; + const infiniteSliding = false; + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[index]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + }, + slideConfig: {infinite: infiniteSliding, sidePreviews: {show: true, size: DEFAULT_SIZE}} as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[index], TEST_MODEL_INFINITE[TEST_MODEL_INFINITE.length - 1]); + checkArrows(index === 0 && !infiniteSliding, (index === IMAGES.length - 1) && !infiniteSliding); + checkSidePreviews(IMAGES[index - 1], IMAGES[0], + index === 0 && !infiniteSliding, (index === IMAGES.length - 1) && !infiniteSliding, TEST_MODEL_INFINITE[TEST_MODEL_INFINITE.length - 1]); + + comp.changeImage.subscribe((res: ImageModalEvent) => { + fail(`shouldn't call 'changeImage' event, when infinite sliding is disabled and you are trying to navigate from the last image to the first one`); + }); + comp.nextImage(Action.CLICK); + }); + + it(`cannot navigate from the first image to the last one if infinite sliding is disabled`, () => { + const index = 0; + const infiniteSliding = false; + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[index]; + comp.isOpen = true; + + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + currentImageConfig: { + loadingConfig: {enable: true, type: LoadingType.STANDARD} as LoadingConfig, + description: {strategy: DescriptionStrategy.ALWAYS_VISIBLE} as Description + }, + slideConfig: {infinite: infiniteSliding, sidePreviews: {show: true, size: DEFAULT_SIZE}} as SlideConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + + fixture.detectChanges(); + + // force detectChanges, because I'm using OnPush strategy and I have to trigger change detection manually to update + // isFirstImage and isLastImage in template file. + // Taken from https://stackoverflow.com/a/52214200/3590376 + comp.ref.detectChanges(); + + checkMainContainer(); + checkCurrentImage(IMAGES[index], TEST_MODEL_INFINITE[0]); + checkArrows(index === 0 && !infiniteSliding, (index === IMAGES.length - 1) && !infiniteSliding); + checkSidePreviews(IMAGES[IMAGES.length - 1], IMAGES[index + 1], + index === 0 && !infiniteSliding, (index === IMAGES.length - 1) && !infiniteSliding, TEST_MODEL_INFINITE[0]); + + comp.changeImage.subscribe((res: ImageModalEvent) => { + fail(`shouldn't call 'changeImage' event, when infinite sliding is disabled and you are trying to navigate from the first image to the last one`); + }); + comp.prevImage(Action.CLICK); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/current-image/current-image.component.ts b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/current-image.component.ts new file mode 100644 index 00000000..defbe997 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/current-image.component.ts @@ -0,0 +1,694 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { + AfterContentInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + EventEmitter, + HostListener, + Inject, + Input, + NgZone, + OnChanges, + OnDestroy, + OnInit, + Output, + PLATFORM_ID, + SimpleChange, + SimpleChanges +} from '@angular/core'; +import { isPlatformBrowser } from '@angular/common'; + +import { Subject, timer } from 'rxjs'; +import { filter, map, switchMap, takeUntil } from 'rxjs/operators'; + +import { AccessibleComponent } from '../accessible.component'; +import { AccessibilityConfig } from '../../model/accessibility.interface'; +import { Action } from '../../model/action.enum'; +import { DescriptionStrategy } from '../../model/description.interface'; +import { Image, ImageModalEvent } from '../../model/image.class'; +import { InternalLibImage } from '../../model/image-internal.class'; +import { Keyboard } from '../../model/keyboard.enum'; +import { KeyboardConfig } from '../../model/keyboard-config.interface'; +import { SlideConfig } from '../../model/slide-config.interface'; +import { NEXT, PREV } from '../../utils/user-input.util'; +import { getIndex } from '../../utils/image.util'; +import { CurrentImageConfig } from '../../model/current-image-config.interface'; +import { ConfigService } from '../../services/config.service'; +import { LibConfig } from '../../model/lib-config.interface'; + +/** + * Interface to describe the Load Event, used to + * emit an event when the image is finally loaded and the spinner has gone. + */ +export interface ImageLoadEvent { + status: boolean; + index: number; + id: number; +} + +/** + * Component with the current image with some additional elements like arrows and side previews. + */ +@Component({ + selector: 'ks-current-image', + styleUrls: ['current-image.scss', '../image-arrows.scss', 'current-image-previews.scss'], + templateUrl: 'current-image.html', + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: false +}) +export class CurrentImageComponent extends AccessibleComponent implements OnInit, OnChanges, AfterContentInit, OnDestroy { + /** + * Unique id (>=0) of the current instance of this library. This is useful when you are using + * the service to call modal gallery without open it manually. + */ + @Input() + id!: number; + /** + * Object of type `InternalLibImage` that represent the visible image. + */ + @Input() + currentImage!: InternalLibImage; + /** + * Array of `InternalLibImage` that represent the model of this library with all images, + * thumbs and so on. + */ + @Input() + images!: InternalLibImage[]; + /** + * Boolean that it is true if the modal gallery is visible. + * If yes, also this component should be visible. + */ + @Input() + // @ts-ignore + isOpen: boolean = false; + + /** + * Output to emit an event when images are loaded. The payload contains an `ImageLoadEvent`. + */ + @Output() + loadImage: EventEmitter = new EventEmitter(); + /** + * Output to emit any changes of the current image. The payload contains an `ImageModalEvent`. + */ + @Output() + changeImage: EventEmitter = new EventEmitter(); + /** + * Output to emit an event when the modal gallery is closed. The payload contains an `ImageModalEvent`. + */ + @Output() + closeGallery: EventEmitter = new EventEmitter(); + + /** + * Subject to play modal-gallery. + */ + private start$ = new Subject(); + /** + * Subject to stop modal-gallery. + */ + private stop$ = new Subject(); + + /** + * Enum of type `Action` that represents a normal action. + * Declared here to be used inside the template. + */ + normalAction: Action = Action.NORMAL; + /** + * Object of type `AccessibilityConfig` to init custom accessibility features. + * For instance, it contains titles, alt texts, aria-labels and so on. + */ + accessibilityConfig: AccessibilityConfig | undefined; + /** + * Object of type `SlideConfig` to get `infinite sliding`. + */ + slideConfig: SlideConfig | undefined; + /** + * Object to configure current image in modal-gallery. + * For instance you can disable navigation on click on current image (enabled by default). + */ + currentImageConfig: CurrentImageConfig | undefined; + /** + * Object of type `KeyboardConfig` to assign custom keys to both ESC, RIGHT and LEFT keyboard's actions. + */ + keyboardConfig: KeyboardConfig | undefined; + /** + * Enum of type `Action` that represents a mouse click on a button. + * Declared here to be used inside the template. + */ + clickAction: Action = Action.CLICK; + /** + * Enum of type `Action` that represents a keyboard action. + * Declared here to be used inside the template. + */ + keyboardAction: Action = Action.KEYBOARD; + /** + * Boolean that it's true when you are watching the first image (currently visible). + * False by default + */ + isFirstImage = false; + /** + * Boolean that it's true when you are watching the last image (currently visible). + * False by default + */ + isLastImage = false; + /** + * Boolean that it's true if an image of the modal gallery is still loading. + * True by default + */ + loading = true; + + // use public ChangeDetectorRef to be able to call it from spec files to trigger change detection + // tslint:disable-next-line:no-any + constructor(@Inject(PLATFORM_ID) private platformId: any, private ngZone: NgZone, + public ref: ChangeDetectorRef, private configService: ConfigService) { + super(); + } + + /** + * Listener to stop the gallery when the mouse pointer is over the current image. + */ + @HostListener('mouseenter') + onMouseEnter(): void { + // if carousel feature is disable, don't do anything in any case + if (!this.slideConfig || !this.slideConfig.playConfig) { + return; + } + if (!this.slideConfig.playConfig.pauseOnHover) { + return; + } + this.stopCarousel(); + } + + /** + * Listener to play the gallery when the mouse pointer leave the current image. + */ + @HostListener('mouseleave') + onMouseLeave(): void { + // if carousel feature is disable, don't do anything in any case + if (!this.slideConfig || !this.slideConfig.playConfig) { + return; + } + if (!this.slideConfig.playConfig.pauseOnHover || !this.slideConfig.playConfig.autoPlay) { + return; + } + this.playCarousel(); + } + + /** + * Method ´ngOnInit´ to init configuration. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called only one time!!! + */ + ngOnInit(): void { + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig || !libConfig.buttonsConfig) { + throw new Error('Internal library error - libConfig and buttonsConfig must be defined'); + } + this.slideConfig = libConfig.slideConfig; + this.accessibilityConfig = libConfig.accessibilityConfig; + this.currentImageConfig = libConfig.currentImageConfig; + this.keyboardConfig = libConfig.keyboardConfig; + } + + /** + * Method ´ngOnChanges´ to update `loading` status and emit events. + * If the gallery is open, then it will also manage boundary arrows and sliding. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called when any data-bound property of a directive changes!!! + */ + ngOnChanges(changes: SimpleChanges): void { + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + const images: SimpleChange = changes.images; + const currentImage: SimpleChange = changes.currentImage; + + if (currentImage && currentImage.previousValue !== currentImage.currentValue) { + this.updateIndexes(); + } else if (images && images.previousValue !== images.currentValue) { + this.updateIndexes(); + } + + const slideConfig: SimpleChange = changes.slideConfig; + if (slideConfig && slideConfig.previousValue !== slideConfig.currentValue) { + this.slideConfig = libConfig.slideConfig; + } + } + + /** + * This is an angular lifecycle hook, so its called automatically by Angular itself. + */ + ngAfterContentInit(): void { + // interval doesn't play well with SSR and protractor, + // so we should run it in the browser and outside Angular + if (isPlatformBrowser(this.platformId)) { + this.ngZone.runOutsideAngular(() => { + this.start$ + .pipe( + map(() => this.slideConfig && this.slideConfig.playConfig && this.slideConfig.playConfig.autoPlay && this.slideConfig.playConfig.interval), + // tslint:disable-next-line:no-any + filter((interval: any) => interval > 0), + switchMap(interval => timer(interval).pipe(takeUntil(this.stop$))) + ) + .subscribe(() => + this.ngZone.run(() => { + if (!this.isLastImage) { + this.nextImage(Action.AUTOPLAY); + } + this.ref.markForCheck(); + }) + ); + + this.start$.next(); + }); + } + } + + /** + * Method to handle keypress based on the `keyboardConfig` input. It gets the code of + * the key that triggered the keypress event to navigate between images or to close the modal gallery. + * @param code string of the key that triggered the keypress event + */ + onKeyPress(code: string): void { + const esc: string = this.keyboardConfig && this.keyboardConfig.esc ? this.keyboardConfig.esc : Keyboard.ESC; + const right: string = this.keyboardConfig && this.keyboardConfig.right ? this.keyboardConfig.right : Keyboard.RIGHT_ARROW; + const left: string = this.keyboardConfig && this.keyboardConfig.left ? this.keyboardConfig.left : Keyboard.LEFT_ARROW; + + switch (code) { + case esc: + this.closeGallery.emit(new ImageModalEvent(this.id, Action.KEYBOARD, true)); + break; + case right: + this.nextImage(Action.KEYBOARD); + break; + case left: + this.prevImage(Action.KEYBOARD); + break; + } + } + + /** + * Method to get the image description based on input params. + * If you provide a full description this will be the visible description, otherwise, + * it will be built using the `Description` object, concatenating its fields. + * @param Image image to get its description. If not provided it will be the current image + * @returns String description of the image (or the current image if not provided) + * @throws an Error if description isn't available + */ + getDescriptionToDisplay(image: Image = this.currentImage): string { + if (!this.currentImageConfig || !this.currentImageConfig.description) { + throw new Error('Description input must be a valid object implementing the Description interface'); + } + + const imageWithoutDescription: boolean = !image.modal || !image.modal.description || image.modal.description === ''; + + switch (this.currentImageConfig.description.strategy) { + case DescriptionStrategy.HIDE_IF_EMPTY: + return imageWithoutDescription ? '' : image.modal.description + ''; + case DescriptionStrategy.ALWAYS_HIDDEN: + return ''; + default: + // ----------- DescriptionStrategy.ALWAYS_VISIBLE ----------------- + return this.buildTextDescription(image, imageWithoutDescription); + } + } + + /** + * Method to get `alt attribute`. + * `alt` specifies an alternate text for an image, if the image cannot be displayed. + * @param Image image to get its alt description. If not provided it will be the current image + * @returns String alt description of the image (or the current image if not provided) + */ + getAltDescriptionByImage(image: Image = this.currentImage): string { + if (!image) { + return ''; + } + return image.modal && image.modal.description ? image.modal.description : `Image ${getIndex(image, this.images) + 1}`; + } + + /** + * Method to get the title attributes based on descriptions. + * This is useful to prevent accessibility issues, because if DescriptionStrategy is ALWAYS_HIDDEN, + * it prevents an empty string as title. + * @param Image image to get its description. If not provided it will be the current image + * @returns String title of the image based on descriptions + * @throws an Error if description isn't available + */ + getTitleToDisplay(image: Image = this.currentImage): string { + if (!this.currentImageConfig || !this.currentImageConfig.description) { + throw new Error('Description input must be a valid object implementing the Description interface'); + } + const imageWithoutDescription: boolean = !image.modal || !image.modal.description || image.modal.description === ''; + const description: string = this.buildTextDescription(image, imageWithoutDescription); + return description; + } + + /** + * Method to get the left side preview image. + * @returns Image the image to show as size preview on the left + */ + getLeftPreviewImage(): Image { + if (!this.slideConfig) { + throw new Error('Internal library error - slideConfig must be defined'); + } + const currentIndex: number = getIndex(this.currentImage, this.images); + if (currentIndex === 0 && this.slideConfig.infinite) { + // the current image is the first one, + // so the previous one is the last image + // because infinite is true + return this.images[this.images.length - 1]; + } + this.handleBoundaries(currentIndex); + return this.images[Math.max(currentIndex - 1, 0)]; + } + + /** + * Method to get the right side preview image. + * @returns Image the image to show as size preview on the right + */ + getRightPreviewImage(): Image { + if (!this.slideConfig) { + throw new Error('Internal library error - slideConfig must be defined'); + } + const currentIndex: number = getIndex(this.currentImage, this.images); + if (currentIndex === this.images.length - 1 && this.slideConfig.infinite) { + // the current image is the last one, + // so the next one is the first image + // because infinite is true + return this.images[0]; + } + this.handleBoundaries(currentIndex); + return this.images[Math.min(currentIndex + 1, this.images.length - 1)]; + } + + /** + * Method called by events from both keyboard and mouse on an image. + * This will invoke the nextImage method. + * @param KeyboardEvent | MouseEvent event payload + * @param Action action that triggered the event or `Action.NORMAL` if not provided + */ + onImageEvent(event: KeyboardEvent | MouseEvent, action: Action = Action.NORMAL): void { + if (!this.currentImageConfig) { + throw new Error('Internal library error - currentImageConfig must be defined'); + } + // check if triggered by a mouse click + // If yes, It should block navigation when navigateOnClick is false + if (action === Action.CLICK && !this.currentImageConfig.navigateOnClick) { + // a user has requested to block navigation via configCurrentImage.navigateOnClick property + return; + } + + const result: number = super.handleImageEvent(event); + if (result === NEXT) { + this.nextImage(action); + } + } + + /** + * Method called by events from both keyboard and mouse on a navigation arrow. + * @param string direction of the navigation that can be either 'next' or 'prev' + * @param KeyboardEvent | MouseEvent event payload + * @param Action action that triggered the event or `Action.NORMAL` if not provided + * @param boolean disable to disable navigation + */ + onNavigationEvent(direction: string, event: KeyboardEvent | MouseEvent, action: Action = Action.NORMAL, disable: boolean = false): void { + if (disable) { + return; + } + const result: number = super.handleNavigationEvent(direction, event); + if (result === NEXT) { + this.nextImage(action); + } else if (result === PREV) { + this.prevImage(action); + } + } + + /** + * Method to go back to the previous image. + * @param action Enum of type `Action` that represents the source + * action that moved back to the previous image. `Action.NORMAL` by default. + */ + prevImage(action: Action = Action.NORMAL): void { + // check if prevImage should be blocked + if (this.isPreventSliding(0)) { + return; + } + const prevImage: InternalLibImage = this.getPrevImage(); + this.loading = !prevImage.previouslyLoaded; + this.changeImage.emit(new ImageModalEvent(this.id, action, getIndex(prevImage, this.images))); + + this.start$.next(); + } + + /** + * Method to go back to the previous image. + * @param action Enum of type `Action` that represents the source + * action that moved to the next image. `Action.NORMAL` by default. + */ + nextImage(action: Action = Action.NORMAL): void { + // check if nextImage should be blocked + if (this.isPreventSliding(this.images.length - 1)) { + return; + } + const nextImage: InternalLibImage = this.getNextImage(); + this.loading = !nextImage.previouslyLoaded; + this.changeImage.emit(new ImageModalEvent(this.id, action, getIndex(nextImage, this.images))); + + this.start$.next(); + } + + /** + * Method to emit an event as loadImage output to say that the requested image if loaded. + * This method is invoked by the javascript's 'load' event on an img tag. + * @param Event event that triggered the load + */ + onImageLoad(event: Event): void { + const loadImageData: ImageLoadEvent = { + status: true, + index: getIndex(this.currentImage, this.images), + id: this.currentImage.id + }; + + this.loadImage.emit(loadImageData); + + this.loading = false; + } + + /** + * Method used by SwipeDirective to support touch gestures (you can also invert the swipe direction with configCurrentImage.invertSwipe). + * @param action String that represent the direction of the swipe action. 'swiperight' by default. + */ + swipe(action = 'swiperight'): void { + if (!this.currentImageConfig) { + throw new Error('Internal library error - currentImageConfig must be defined'); + } + switch (action) { + case 'swiperight': + if (this.currentImageConfig.invertSwipe) { + this.prevImage(Action.SWIPE); + } else { + this.nextImage(Action.SWIPE); + } + break; + case 'swipeleft': + if (this.currentImageConfig.invertSwipe) { + this.nextImage(Action.SWIPE); + } else { + this.prevImage(Action.SWIPE); + } + break; + // case this.SWIPE_ACTION.UP: + // break; + // case this.SWIPE_ACTION.DOWN: + // break; + } + } + + /** + * Method used in `modal-gallery.component` to get the index of an image to delete. + * @param Image image to get the index, or the visible image, if not passed + * @returns number the index of the image + */ + getIndexToDelete(image: Image = this.currentImage): number { + return getIndex(image, this.images); + } + + /** + * Method to play modal gallery. + */ + playCarousel(): void { + this.start$.next(); + } + + /** + * Stops modal gallery from cycling through items. + */ + stopCarousel(): void { + this.stop$.next(); + } + + /** + * Method to cleanup resources. In fact, this will stop the modal gallery. + * This is an angular lifecycle hook that is called when this component is destroyed. + */ + ngOnDestroy(): void { + this.stopCarousel(); + } + + /** + * Private method to update both `isFirstImage` and `isLastImage` based on + * the index of the current image. + * @param number currentIndex is the index of the current image + */ + private handleBoundaries(currentIndex: number): void { + if (this.images.length === 1) { + this.isFirstImage = true; + this.isLastImage = true; + this.ref.markForCheck(); + return; + } + if (!this.slideConfig || this.slideConfig.infinite === true) { + // infinite sliding enabled + this.isFirstImage = false; + this.isLastImage = false; + this.ref.markForCheck(); + } else { + // execute this only if infinite sliding is disabled + switch (currentIndex) { + case 0: + this.isFirstImage = true; + this.isLastImage = false; + this.ref.markForCheck(); + break; + case this.images.length - 1: + this.isFirstImage = false; + this.isLastImage = true; + this.ref.markForCheck(); + break; + default: + this.isFirstImage = false; + this.isLastImage = false; + this.ref.markForCheck(); + break; + } + } + } + + /** + * Private method to check if next/prev actions should be blocked. + * It checks if slideConfig.infinite === false and if the image index is equals to the input parameter. + * If yes, it returns true to say that sliding should be blocked, otherwise not. + * @param number boundaryIndex that could be either the beginning index (0) or the last index + * of images (this.images.length - 1). + * @returns boolean true if slideConfig.infinite === false and the current index is + * either the first or the last one. + */ + private isPreventSliding(boundaryIndex: number): boolean { + return !!this.slideConfig && this.slideConfig.infinite === false && getIndex(this.currentImage, this.images) === boundaryIndex; + } + + /** + * Private method to get the next index. + * This is necessary because at the end, when you call next again, you'll go to the first image. + * That happens because all modal images are shown like in a circle. + */ + private getNextImage(): InternalLibImage { + const currentIndex: number = getIndex(this.currentImage, this.images); + let newIndex = 0; + if (currentIndex >= 0 && currentIndex < this.images.length - 1) { + newIndex = currentIndex + 1; + } else { + newIndex = 0; // start from the first index + } + return this.images[newIndex]; + } + + /** + * Private method to get the previous index. + * This is necessary because at index 0, when you call prev again, you'll go to the last image. + * That happens because all modal images are shown like in a circle. + */ + private getPrevImage(): InternalLibImage { + const currentIndex: number = getIndex(this.currentImage, this.images); + let newIndex = 0; + if (currentIndex > 0 && currentIndex <= this.images.length - 1) { + newIndex = currentIndex - 1; + } else { + newIndex = this.images.length - 1; // start from the last index + } + return this.images[newIndex]; + } + + /** + * Private method to build a text description. + * This is used also to create titles. + * @param Image image to get its description. If not provided it will be the current image. + * @param boolean imageWithoutDescription is a boolean that it's true if the image hasn't a 'modal' description. + * @returns String description built concatenating image fields with a specific logic. + */ + private buildTextDescription(image: Image, imageWithoutDescription: boolean): string { + if (!this.currentImageConfig || !this.currentImageConfig.description) { + throw new Error('Description input must be a valid object implementing the Description interface'); + } + + // If customFullDescription use it, otherwise proceed to build a description + if (this.currentImageConfig.description.customFullDescription && this.currentImageConfig.description.customFullDescription !== '') { + return this.currentImageConfig.description.customFullDescription; + } + + const currentIndex: number = getIndex(image, this.images); + // If the current image hasn't a description, + // prevent to write the ' - ' (or this.description.beforeTextDescription) + + const prevDescription: string = this.currentImageConfig.description.imageText ? this.currentImageConfig.description.imageText : ''; + const midSeparator: string = this.currentImageConfig.description.numberSeparator ? this.currentImageConfig.description.numberSeparator : ''; + const middleDescription: string = currentIndex + 1 + midSeparator + this.images.length; + + if (imageWithoutDescription) { + return prevDescription + middleDescription; + } + + const currImgDescription: string = image.modal && image.modal.description ? image.modal.description : ''; + const endDescription: string = this.currentImageConfig.description.beforeTextDescription + currImgDescription; + return prevDescription + middleDescription + endDescription; + } + + /** + * Private method to call handleBoundaries when ngOnChanges is called. + */ + private updateIndexes(): void { + try { + if (this.isOpen) { + const index: number = getIndex(this.currentImage, this.images); + this.handleBoundaries(index); + } + } catch (err) { + console.error('Cannot get the current image index in current-image'); + throw err; + } + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/current-image/current-image.html b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/current-image.html new file mode 100644 index 00000000..a526bc30 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/current-image.html @@ -0,0 +1,107 @@ +
+ +
+ + + + + + + {{leftPreview.modal.alt ? leftPreview.modal.alt : getAltDescriptionByImage(leftPreview)}} + + + + + +
+ + +
+ + + + + {{currentImage.modal.alt ? currentImage.modal.alt : getAltDescriptionByImage()}} + +
+
+
+ +
+ + + {{rightPreview.modal.alt ? rightPreview.modal.alt : getAltDescriptionByImage(rightPreview)}} + + + + + + + + + + + + + +
+
diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/current-image/current-image.scss b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/current-image.scss new file mode 100644 index 00000000..ea5498d0 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/current-image.scss @@ -0,0 +1,175 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// all svgs are converted to base 64 with this website http://b64.io/ + +$main-img-container-margin-top: 20px; +$main-img-container-margin-bottom: 20px; + +$curr-img-max-width-trick: 70vw; +$curr-img-max-width: 80vw; +$curr-img-max-height: 60vh; + +$nav-animation-time: 1s; +$nav-transition-time: .5s; +$nav-side-margin: 15px; + +$figcaption-padding: 10px; +$figcaption-position: absolute; +$figcaption-bottom: 0; +$figcaption-left: 0; +$figcaption-right: 0; + +:host { + display: flex; + flex-direction: column; + justify-content: center; +} + +.main-image-container { + display: flex; + //flex-grow: 1; + flex-direction: row; + align-items: center; + justify-content: space-between; + //margin-top: $main-img-container-margin-top; + //margin-bottom: $main-img-container-margin-bottom; + + .nav { + animation: animatezoom $nav-animation-time; + cursor: pointer; + transition: all $nav-transition-time; + + &:hover { + transform: scale(1.1); + } + } + + > .left-sub-container { + display: flex; + flex-direction: row; + justify-content: space-around; + align-items: center; + + > .nav-left { + @extend .nav; + margin-right: 5px; + margin-left: $nav-side-margin; + + &.no-pointer { + cursor: default !important; + } + } + } + + > .right-sub-container { + display: flex; + flex-direction: row; + justify-content: space-around; + align-items: center; + + > .nav-right { + @extend .nav; + margin-right: $nav-side-margin; + margin-left: 5px; + + &.no-pointer { + cursor: default !important; + } + } + } + + #current-figure { + animation: fadein-visible .8s; + text-align: center; + margin: 0; // => Removes margin from every figure to prevent problem when resizing horizontally on tablets and smartphones + position: relative; + > .current-image { + display: block; + > img { + // display: block; + // don't use this + // Bootstrap 4 img-fluid class uses max-width: 100% and height: auto + max-width: 100%; // `width: 100%` is ok on Chrome and Firefox, but not on Safari + height: auto; + display: block; + &.unclickable { + cursor: not-allowed; + } + } + } + + + & figcaption { + padding: $figcaption-padding; + position: $figcaption-position; + bottom: $figcaption-bottom; + left: $figcaption-left; + right: $figcaption-right; + + .description { + font-weight: bold; + text-align: center; + } + } + } +} + +.current-image > img { + height: auto; + // Thanks to vh ad vw I can resize the image when reducing browser's window both vertically and horizontally + max-width: $curr-img-max-width; + max-height: $curr-img-max-height; + cursor: pointer; + + // trick found here https://stackoverflow.com/a/37600130/3590376 + // Using a media query I can set a max width + @media screen and (min-width: $curr-img-max-width-trick) { + // Thanks to vh ad vw I can resize the image when reducing browser's window both vertically and horizontally + max-width: $curr-img-max-width-trick; + } +} + +@mixin fadein($opacity-from, $opacity-to) { + from { + opacity: $opacity-from; + } + to { + opacity: $opacity-to; + } +} + +@keyframes fadein-visible { + @include fadein(0, 1); +} + +@keyframes fadein-semi-visible05 { + @include fadein(0, .5); +} + +@keyframes fadein-semi-visible08 { + @include fadein(0, .8); +} + +@keyframes fadein-semi-visible09 { + @include fadein(0, .9); +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/loading-spinner.component.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/loading-spinner.component.spec.ts new file mode 100644 index 00000000..965234fb --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/loading-spinner.component.spec.ts @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2017-2021 Stefano Cappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { DebugElement } from '@angular/core'; +import { By } from '@angular/platform-browser'; + +import { LoadingSpinnerComponent } from './loading-spinner.component'; +import { AccessibilityConfig } from '../../../model/accessibility.interface'; +import { LoadingConfig, LoadingType } from '../../../model/loading-config.interface'; +import { KS_DEFAULT_ACCESSIBILITY_CONFIG } from '../../accessibility-default'; + +let comp: LoadingSpinnerComponent; +let fixture: ComponentFixture; + +const CUSTOM_ACCESSIBILITY: AccessibilityConfig = Object.assign({}, KS_DEFAULT_ACCESSIBILITY_CONFIG); +CUSTOM_ACCESSIBILITY.loadingSpinnerAriaLabel = 'custom loadingSpinnerAriaLabel'; +CUSTOM_ACCESSIBILITY.loadingSpinnerTitle = 'custom loadingSpinnerTitle'; + +const VISIBLE_CONFIG: LoadingConfig[] = [ + {enable: true, type: LoadingType.STANDARD}, + {enable: true, type: LoadingType.BARS}, + {enable: true, type: LoadingType.CIRCULAR}, + {enable: true, type: LoadingType.DOTS}, + {enable: true, type: LoadingType.CUBE_FLIPPING}, + {enable: true, type: LoadingType.CIRCLES}, + {enable: true, type: LoadingType.EXPLOSING_SQUARES} +]; + +function initTestBed(): void { + TestBed.configureTestingModule({ + declarations: [LoadingSpinnerComponent] + }); +} + +describe('LoadingSpinnerComponent', () => { + beforeEach(() => { + initTestBed(); + fixture = TestBed.createComponent(LoadingSpinnerComponent); + comp = fixture.componentInstance; + }); + + it('should instantiate it', () => expect(comp).not.toBeNull()); + + describe('---YES---', () => { + VISIBLE_CONFIG.forEach((loadingConfig: LoadingConfig, i: number) => { + it(`should display loading spinner with default accessibility config. Test i=${i}`, () => { + comp.loadingConfig = loadingConfig; + comp.accessibilityConfig = KS_DEFAULT_ACCESSIBILITY_CONFIG; + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + const spinnerContainer: DebugElement = element.query(By.css('div')); + expect(spinnerContainer).not.toBeUndefined(); + expect(spinnerContainer.name).toBe('div'); + expect(spinnerContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.loadingSpinnerAriaLabel); + expect(spinnerContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.loadingSpinnerTitle); + + switch (loadingConfig.type) { + case LoadingType.STANDARD: + const cssLoadLoader: DebugElement = element.query(By.css('div.cssload-loader')); + expect(cssLoadLoader).not.toBeUndefined(); + expect(cssLoadLoader.name).toBe('div'); + const cssloadInner1: DebugElement = element.query(By.css('div.cssload-inner.cssload-one')); + expect(cssloadInner1).not.toBeUndefined(); + expect(cssloadInner1.name).toBe('div'); + const cssloadInner2: DebugElement = element.query(By.css('div.cssload-inner.cssload-two')); + expect(cssloadInner2).not.toBeUndefined(); + expect(cssloadInner2.name).toBe('div'); + const cssloadInner3: DebugElement = element.query(By.css('div.cssload-inner.cssload-three')); + expect(cssloadInner3).not.toBeUndefined(); + expect(cssloadInner3.name).toBe('div'); + break; + case LoadingType.DOTS: + const dotsSpinner: DebugElement = element.query(By.css('div.loader-dots')); + expect(dotsSpinner).not.toBeUndefined(); + expect(dotsSpinner.name).toBe('div'); + break; + case LoadingType.CIRCULAR: + const circularSpinner: DebugElement = element.query(By.css('div.loader-circular')); + expect(circularSpinner).not.toBeUndefined(); + expect(circularSpinner.name).toBe('div'); + break; + case LoadingType.BARS: + const barsSpinner: DebugElement = element.query(By.css('div.loader-bars')); + expect(barsSpinner).not.toBeUndefined(); + expect(barsSpinner.name).toBe('div'); + break; + case LoadingType.CUBE_FLIPPING: + const cubeFlippingSpinner: DebugElement = element.query(By.css('div.cube-wrapper')); + expect(cubeFlippingSpinner).not.toBeUndefined(); + expect(cubeFlippingSpinner.name).toBe('div'); + const cssCubeFolding: DebugElement = element.query(By.css('div.cube-wrapper > div.cube-folding')); + expect(cssCubeFolding).not.toBeUndefined(); + expect(cssCubeFolding.name).toBe('div'); + const cssLeaf1: DebugElement = element.query(By.css('div.cube-wrapper > div.cube-folding >.leaf1')); + expect(cssLeaf1).not.toBeUndefined(); + expect(cssLeaf1.name).toBe('span'); + const cssLeaf2: DebugElement = element.query(By.css('div.cube-wrapper > div.cube-folding >.leaf2')); + expect(cssLeaf2).not.toBeUndefined(); + expect(cssLeaf2.name).toBe('span'); + const cssLeaf3: DebugElement = element.query(By.css('div.cube-wrapper> div.cube-folding >.leaf3')); + expect(cssLeaf3).not.toBeUndefined(); + expect(cssLeaf3.name).toBe('span'); + break; + case LoadingType.CIRCLES: + const circlesSpinner: DebugElement = element.query(By.css('#preloader')); + expect(circlesSpinner).not.toBeUndefined(); + expect(circlesSpinner.name).toBe('div'); + const cssLoader: DebugElement = element.query(By.css('#loader')); + expect(cssLoader).not.toBeUndefined(); + expect(cssLoader.name).toBe('div'); + break; + case LoadingType.EXPLOSING_SQUARES: + const explosingSquaresSpinner: DebugElement = element.query(By.css('div.loader')); + expect(explosingSquaresSpinner).not.toBeUndefined(); + expect(explosingSquaresSpinner.name).toBe('div'); + explosingSquaresSpinner.children.forEach((el: DebugElement) => { + expect(el.name).toBe('span'); + }); + break; + } + }); + }); + + VISIBLE_CONFIG.forEach((loadingConfig: LoadingConfig, i: number) => { + it(`should display loading spinner with CUSTOM accessibility config. Test i=${i}`, () => { + comp.loadingConfig = loadingConfig; + comp.accessibilityConfig = CUSTOM_ACCESSIBILITY; + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + const spinnerContainer: DebugElement = element.query(By.css('div')); + expect(spinnerContainer).not.toBeUndefined(); + expect(spinnerContainer.name).toBe('div'); + expect(spinnerContainer.attributes['aria-label']).toBe(CUSTOM_ACCESSIBILITY.loadingSpinnerAriaLabel); + expect(spinnerContainer.properties.title).toBe(CUSTOM_ACCESSIBILITY.loadingSpinnerTitle); + + switch (loadingConfig.type) { + case LoadingType.STANDARD: + const cssLoadLoader: DebugElement = element.query(By.css('div.cssload-loader')); + expect(cssLoadLoader).not.toBeUndefined(); + expect(cssLoadLoader.name).toBe('div'); + const cssloadInner1: DebugElement = element.query(By.css('div.cssload-inner.cssload-one')); + expect(cssloadInner1).not.toBeUndefined(); + expect(cssloadInner1.name).toBe('div'); + const cssloadInner2: DebugElement = element.query(By.css('div.cssload-inner.cssload-two')); + expect(cssloadInner2).not.toBeUndefined(); + expect(cssloadInner2.name).toBe('div'); + const cssloadInner3: DebugElement = element.query(By.css('div.cssload-inner.cssload-three')); + expect(cssloadInner3).not.toBeUndefined(); + expect(cssloadInner3.name).toBe('div'); + break; + case LoadingType.DOTS: + const dotsSpinner: DebugElement = element.query(By.css('div.loader-dots')); + expect(dotsSpinner).not.toBeUndefined(); + expect(dotsSpinner.name).toBe('div'); + break; + case LoadingType.CIRCULAR: + const circularSpinner: DebugElement = element.query(By.css('div.loader-circular')); + expect(circularSpinner).not.toBeUndefined(); + expect(circularSpinner.name).toBe('div'); + break; + case LoadingType.BARS: + const barsSpinner: DebugElement = element.query(By.css('div.loader-bars')); + expect(barsSpinner).not.toBeUndefined(); + expect(barsSpinner.name).toBe('div'); + break; + case LoadingType.CUBE_FLIPPING: + const cubeFlippingSpinner: DebugElement = element.query(By.css('div.cube-wrapper')); + expect(cubeFlippingSpinner).not.toBeUndefined(); + expect(cubeFlippingSpinner.name).toBe('div'); + const cssCubeFolding: DebugElement = element.query(By.css('div.cube-wrapper > div.cube-folding')); + expect(cssCubeFolding).not.toBeUndefined(); + expect(cssCubeFolding.name).toBe('div'); + const cssLeaf1: DebugElement = element.query(By.css('div.cube-wrapper > div.cube-folding >.leaf1')); + expect(cssLeaf1).not.toBeUndefined(); + expect(cssLeaf1.name).toBe('span'); + const cssLeaf2: DebugElement = element.query(By.css('div.cube-wrapper > div.cube-folding >.leaf2')); + expect(cssLeaf2).not.toBeUndefined(); + expect(cssLeaf2.name).toBe('span'); + const cssLeaf3: DebugElement = element.query(By.css('div.cube-wrapper> div.cube-folding >.leaf3')); + expect(cssLeaf3).not.toBeUndefined(); + expect(cssLeaf3.name).toBe('span'); + break; + case LoadingType.CIRCLES: + const circlesSpinner: DebugElement = element.query(By.css('#preloader')); + expect(circlesSpinner).not.toBeUndefined(); + expect(circlesSpinner.name).toBe('div'); + const cssLoader: DebugElement = element.query(By.css('#loader')); + expect(cssLoader).not.toBeUndefined(); + expect(cssLoader.name).toBe('div'); + break; + case LoadingType.EXPLOSING_SQUARES: + const explosingSquaresSpinner: DebugElement = element.query(By.css('div.loader')); + expect(explosingSquaresSpinner).not.toBeUndefined(); + expect(explosingSquaresSpinner.name).toBe('div'); + explosingSquaresSpinner.children.forEach((el: DebugElement) => { + expect(el.name).toBe('span'); + }); + break; + } + }); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/loading-spinner.component.ts b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/loading-spinner.component.ts new file mode 100644 index 00000000..d993ee03 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/loading-spinner.component.ts @@ -0,0 +1,97 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; + +import { AccessibilityConfig } from '../../../model/accessibility.interface'; +import { LoadingConfig, LoadingType } from '../../../model/loading-config.interface'; + +/** + * Component with the loading spinner + */ +@Component({ + selector: 'ks-loading-spinner', + styleUrls: [ + 'style-loading-spinner-standard.css', + 'style-loading-spinner-dots.css', + 'style-loading-spinner-bars.css', + 'style-loading-spinner-circular.css', + 'style-loading-spinner-cube-flipping.css', + 'style-loading-spinner-circles.css', + 'style-loading-spinner-explosing-squares.scss' + ], + templateUrl: 'loading-spinner.html', + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: false +}) +export class LoadingSpinnerComponent { + /** + * Object of type `LoadingConfig` exposed to the template. + * It contains a field to choose a loading spinner. + */ + @Input() + loadingConfig!: LoadingConfig; + /** + * Object of type `AccessibilityConfig` to init custom accessibility features. + * For instance, it contains titles, alt texts, aria-labels and so on. + */ + @Input() + accessibilityConfig!: AccessibilityConfig; + + /** + * Enum of type `LoadingType` to choose the standard loading spinner. + * Declared here to be used inside the template. + */ + loadingStandard: LoadingType = LoadingType.STANDARD; + /** + * Enum of type `LoadingType` to choose the bars loading spinner. + * Declared here to be used inside the template. + */ + loadingBars: LoadingType = LoadingType.BARS; + /** + * Enum of type `LoadingType` to choose the circular loading spinner. + * Declared here to be used inside the template. + */ + loadingCircular: LoadingType = LoadingType.CIRCULAR; + /** + * Enum of type `LoadingType` to choose the dots loading spinner. + * Declared here to be used inside the template. + */ + loadingDots: LoadingType = LoadingType.DOTS; + /** + * Enum of type `LoadingType` to choose the cube flipping loading spinner. + * Declared here to be used inside the template. + */ + loadingCubeFlipping: LoadingType = LoadingType.CUBE_FLIPPING; + /** + * Enum of type `LoadingType` to choose the circles loading spinner. + * Declared here to be used inside the template. + */ + loadingCircles: LoadingType = LoadingType.CIRCLES; + /** + * Enum of type `LoadingType` to choose the explosing squares loading spinner. + * Declared here to be used inside the template. + */ + loadingExplosingSquares: LoadingType = LoadingType.EXPLOSING_SQUARES; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/loading-spinner.html b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/loading-spinner.html new file mode 100644 index 00000000..000e4df5 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/loading-spinner.html @@ -0,0 +1,48 @@ +
+ + + +
+
+
+
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+ + + + +
+
+
+ +
+
+
+
+ +
+ + + + +
+
+
+
diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-bars.css b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-bars.css new file mode 100644 index 00000000..7bc19e12 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-bars.css @@ -0,0 +1,65 @@ +/* Taken from https://projects.lukehaas.me/css-loader-barss/ */ + +.loader-bars, +.loader-bars:before, +.loader-bars:after { + background: #fefcff; + -webkit-animation: load1 1s infinite ease-in-out; + animation: load1 1s infinite ease-in-out; + width: 1em; + height: 4em; +} +.loader-bars { + position: absolute; + top: 0; + bottom: 0; + right: 0; + left: 0; + color: #fefcff; + text-indent: -9999em; + margin: auto; + font-size: 11px; + -webkit-transform: translateZ(0); + -ms-transform: translateZ(0); + transform: translateZ(0); + -webkit-animation-delay: -0.16s; + animation-delay: -0.16s; +} +.loader-bars:before, +.loader-bars:after { + position: absolute; + top: 0; + content: ''; +} +.loader-bars:before { + left: -1.5em; + -webkit-animation-delay: -0.32s; + animation-delay: -0.32s; +} +.loader-bars:after { + left: 1.5em; +} +@-webkit-keyframes load1 { + 0%, + 80%, + 100% { + box-shadow: 0 0; + height: 4em; + } + 40% { + box-shadow: 0 -2em; + height: 5em; + } +} +@keyframes load1 { + 0%, + 80%, + 100% { + box-shadow: 0 0; + height: 4em; + } + 40% { + box-shadow: 0 -2em; + height: 5em; + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-circles.css b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-circles.css new file mode 100644 index 00000000..97c1052b --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-circles.css @@ -0,0 +1,73 @@ +/* Taken from https://codepen.io/WebSonata/pen/bRaONB */ + +#preloader { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +#loader { + display: block; + position: relative; + left: 50%; + top: 50%; + width: 100px; + height: 100px; + margin: -75px 0 0 -75px; + border-radius: 50%; + border: 3px solid transparent; + border-top-color: #B4B4B4; + -webkit-animation: spin 2s linear infinite; + animation: spin 2s linear infinite; +} +#loader:before { + content: ""; + position: absolute; + top: 5px; + left: 5px; + right: 5px; + bottom: 5px; + border-radius: 50%; + border: 3px solid transparent; + border-top-color: #D9D9D9; + -webkit-animation: spin 3s linear infinite; + animation: spin 3s linear infinite; +} +#loader:after { + content: ""; + position: absolute; + top: 15px; + left: 15px; + right: 15px; + bottom: 15px; + border-radius: 50%; + border: 3px solid transparent; + border-top-color: #FFF; + -webkit-animation: spin 1.5s linear infinite; + animation: spin 1.5s linear infinite; +} +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + -ms-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + -ms-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + -ms-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + -ms-transform: rotate(360deg); + transform: rotate(360deg); + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-circular.css b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-circular.css new file mode 100644 index 00000000..5d5a545f --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-circular.css @@ -0,0 +1,47 @@ +/* Taken from https://projects.lukehaas.me/css-loaders/ */ + +.loader-circular, +.loader-circular:after { + border-radius: 50%; + width: 10em; + height: 10em; +} +.loader-circular { + position: absolute; + top: 0; + bottom: 0; + right: 0; + left: 0; + margin: auto; + font-size: 10px; + text-indent: -9999em; + border-top: 1.1em solid rgba(255, 255, 255, 0.2); + border-right: 1.1em solid rgba(255, 255, 255, 0.2); + border-bottom: 1.1em solid rgba(255, 255, 255, 0.2); + border-left: 1.1em solid #ffffff; + -webkit-transform: translateZ(0); + -ms-transform: translateZ(0); + transform: translateZ(0); + -webkit-animation: load8 1.1s infinite linear; + animation: load8 1.1s infinite linear; +} +@-webkit-keyframes load8 { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@keyframes load8 { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-cube-flipping.css b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-cube-flipping.css new file mode 100644 index 00000000..1ee71758 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-cube-flipping.css @@ -0,0 +1,177 @@ +/* Based on https://codepen.io/nikhil8krishnan/pen/dMEzGx */ + +.cube-folding { + width: 50px; + height: 50px; + display: inline-block; + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -webkit-transform: rotate(45deg); + transform: rotate(45deg); + font-size: 0; +} +.cube-folding span { + position: relative; + width: 25px; + height: 25px; + -moz-transform: scale(1.1); + -ms-transform: scale(1.1); + -webkit-transform: scale(1.1); + transform: scale(1.1); + display: inline-block; +} +.cube-folding span::before { + content: ''; + background-color: white; + position: absolute; + left: 0; + top: 0; + display: block; + width: 25px; + height: 25px; + -moz-transform-origin: 100% 100%; + -ms-transform-origin: 100% 100%; + -webkit-transform-origin: 100% 100%; + transform-origin: 100% 100%; + -moz-animation: folding 2.5s infinite linear both; + -webkit-animation: folding 2.5s infinite linear both; + animation: folding 2.5s infinite linear both; +} +.cube-folding .leaf2 { + -moz-transform: rotateZ(90deg) scale(1.1); + -ms-transform: rotateZ(90deg) scale(1.1); + -webkit-transform: rotateZ(90deg) scale(1.1); + transform: rotateZ(90deg) scale(1.1); +} +.cube-folding .leaf2::before { + -moz-animation-delay: 0.3s; + -webkit-animation-delay: 0.3s; + animation-delay: 0.3s; + background-color: #f2f2f2; +} +.cube-folding .leaf3 { + -moz-transform: rotateZ(270deg) scale(1.1); + -ms-transform: rotateZ(270deg) scale(1.1); + -webkit-transform: rotateZ(270deg) scale(1.1); + transform: rotateZ(270deg) scale(1.1); +} +.cube-folding .leaf3::before { + -moz-animation-delay: 0.9s; + -webkit-animation-delay: 0.9s; + animation-delay: 0.9s; + background-color: #f2f2f2; +} +.cube-folding .leaf4 { + -moz-transform: rotateZ(180deg) scale(1.1); + -ms-transform: rotateZ(180deg) scale(1.1); + -webkit-transform: rotateZ(180deg) scale(1.1); + transform: rotateZ(180deg) scale(1.1); +} +.cube-folding .leaf4::before { + -moz-animation-delay: 0.6s; + -webkit-animation-delay: 0.6s; + animation-delay: 0.6s; + background-color: #e6e6e6; +} + +@-moz-keyframes folding { + 0%, 10% { + -moz-transform: perspective(140px) rotateX(-180deg); + transform: perspective(140px) rotateX(-180deg); + opacity: 0; + } + 25%, 75% { + -moz-transform: perspective(140px) rotateX(0deg); + transform: perspective(140px) rotateX(0deg); + opacity: 1; + } + 90%, 100% { + -moz-transform: perspective(140px) rotateY(180deg); + transform: perspective(140px) rotateY(180deg); + opacity: 0; + } +} +@-webkit-keyframes folding { + 0%, 10% { + -webkit-transform: perspective(140px) rotateX(-180deg); + transform: perspective(140px) rotateX(-180deg); + opacity: 0; + } + 25%, 75% { + -webkit-transform: perspective(140px) rotateX(0deg); + transform: perspective(140px) rotateX(0deg); + opacity: 1; + } + 90%, 100% { + -webkit-transform: perspective(140px) rotateY(180deg); + transform: perspective(140px) rotateY(180deg); + opacity: 0; + } +} +@keyframes folding { + 0%, 10% { + -moz-transform: perspective(140px) rotateX(-180deg); + -ms-transform: perspective(140px) rotateX(-180deg); + -webkit-transform: perspective(140px) rotateX(-180deg); + transform: perspective(140px) rotateX(-180deg); + opacity: 0; + } + 25%, 75% { + -moz-transform: perspective(140px) rotateX(0deg); + -ms-transform: perspective(140px) rotateX(0deg); + -webkit-transform: perspective(140px) rotateX(0deg); + transform: perspective(140px) rotateX(0deg); + opacity: 1; + } + 90%, 100% { + -moz-transform: perspective(140px) rotateY(180deg); + -ms-transform: perspective(140px) rotateY(180deg); + -webkit-transform: perspective(140px) rotateY(180deg); + transform: perspective(140px) rotateY(180deg); + opacity: 0; + } +} +.cube-wrapper { + position: fixed; + left: 50%; + top: 50%; + margin-top: -50px; + margin-left: -50px; + width: 100px; + height: 100px; + text-align: center; +} + +@-moz-keyframes text { + 100% { + top: 35px; + } +} +@-webkit-keyframes text { + 100% { + top: 35px; + } +} +@keyframes text { + 100% { + top: 35px; + } +} +@-moz-keyframes shadow { + 100% { + bottom: -18px; + width: 100px; + } +} +@-webkit-keyframes shadow { + 100% { + bottom: -18px; + width: 100px; + } +} +@keyframes shadow { + 100% { + bottom: -18px; + width: 100px; + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-dots.css b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-dots.css new file mode 100644 index 00000000..ff9b53b2 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-dots.css @@ -0,0 +1,77 @@ +/* Taken from https://projects.lukehaas.me/css-loaders/ */ + +.loader-dots { + position: absolute; + top: 0; + bottom: 0; + right: 0; + left: 0; + color: #fefcff; + font-size: 10px; + margin: auto; + width: 1em; + height: 1em; + border-radius: 50%; + text-indent: -9999em; + -webkit-animation: load4 1.3s infinite linear; + animation: load4 1.3s infinite linear; + -webkit-transform: translateZ(0); + -ms-transform: translateZ(0); + transform: translateZ(0); +} + +@-webkit-keyframes load4 { + 0%, + 100% { + box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0; + } + 12.5% { + box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em; + } + 25% { + box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em; + } + 37.5% { + box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em; + } + 50% { + box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em; + } + 62.5% { + box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em; + } + 75% { + box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0; + } + 87.5% { + box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em; + } +} + +@keyframes load4 { + 0%, + 100% { + box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0; + } + 12.5% { + box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em; + } + 25% { + box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em; + } + 37.5% { + box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em; + } + 50% { + box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em; + } + 62.5% { + box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em; + } + 75% { + box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0; + } + 87.5% { + box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em; + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-explosing-squares.scss b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-explosing-squares.scss new file mode 100644 index 00000000..af47c943 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-explosing-squares.scss @@ -0,0 +1,71 @@ +/* Taken from https://codepen.io/WebSonata/pen/bRaONB */ +@keyframes loader { + 0%, 10%, 100% { + width: 60px; + height: 60px; + } + 65% { + width: 150px; + height: 150px; + } +} +@keyframes loaderBlock { + 0%, 30% { + transform: rotate(0); + } + 55% { + background-color: #B4B4B4; + } + 100% { + transform: rotate(90deg); + + } +} +@keyframes loaderBlockInverse { + 0%, 20% { + transform: rotate(0); + } + 55% { + background-color: #D9D9D9; + } + 100% { + transform: rotate(-90deg); + } +} +.loader { + position: absolute; + top: 50%; + left: 50%; + width: 60px; + height: 60px; + transform: translate(-50%, -50%) rotate(45deg) translate3d(0,0,0); + animation: loader 1.2s infinite ease-in-out; + + span { + position: absolute; + display: block; + width: 40px; + height: 40px; + background-color: #FFF; + animation: loaderBlock 1.2s infinite ease-in-out both; + + &:nth-child(1) { + top: 0; + left: 0; + } + &:nth-child(2) { + top: 0; + right: 0; + animation: loaderBlockInverse 1.2s infinite ease-in-out both; + } + &:nth-child(3) { + bottom: 0; + left: 0; + animation: loaderBlockInverse 1.2s infinite ease-in-out both; + } + &:nth-child(4) { + bottom: 0; + right: 0; + } + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-standard.css b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-standard.css new file mode 100644 index 00000000..dff57f33 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/current-image/loading-spinner/style-loading-spinner-standard.css @@ -0,0 +1,202 @@ +/* taken from https://codepen.io/martinvd/pen/xbQJom */ + +.cssload-loader { + position: absolute; + top: 0; + bottom: 0; + right: 0; + left: 0; + margin: auto; + width: 64px; + height: 64px; + border-radius: 50%; + -o-border-radius: 50%; + -ms-border-radius: 50%; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + perspective: 800px; +} + +.cssload-inner { + position: absolute; + width: 100%; + height: 100%; + box-sizing: border-box; + -o-box-sizing: border-box; + -ms-box-sizing: border-box; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + border-radius: 50%; + -o-border-radius: 50%; + -ms-border-radius: 50%; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; +} + +.cssload-inner.cssload-one { + left: 0%; + top: 0%; + animation: cssload-rotate-one 0.6s linear infinite; + -o-animation: cssload-rotate-one 0.6s linear infinite; + -ms-animation: cssload-rotate-one 0.6s linear infinite; + -webkit-animation: cssload-rotate-one 0.6s linear infinite; + -moz-animation: cssload-rotate-one 0.6s linear infinite; + border-bottom: 3px solid rgba(255, 255, 255, 0.99); +} + +.cssload-inner.cssload-two { + right: 0%; + top: 0%; + animation: cssload-rotate-two 0.6s linear infinite; + -o-animation: cssload-rotate-two 0.6s linear infinite; + -ms-animation: cssload-rotate-two 0.6s linear infinite; + -webkit-animation: cssload-rotate-two 0.6s linear infinite; + -moz-animation: cssload-rotate-two 0.6s linear infinite; + border-right: 3px solid rgb(255, 255, 255); +} + +.cssload-inner.cssload-three { + right: 0%; + bottom: 0%; + animation: cssload-rotate-three 0.6s linear infinite; + -o-animation: cssload-rotate-three 0.6s linear infinite; + -ms-animation: cssload-rotate-three 0.6s linear infinite; + -webkit-animation: cssload-rotate-three 0.6s linear infinite; + -moz-animation: cssload-rotate-three 0.6s linear infinite; + border-top: 3px solid rgb(255, 255, 255); +} + +@keyframes cssload-rotate-one { + 0% { + transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg); + } + 100% { + transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg); + } +} + +@-o-keyframes cssload-rotate-one { + 0% { + -o-transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg); + } + 100% { + -o-transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg); + } +} + +@-ms-keyframes cssload-rotate-one { + 0% { + -ms-transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg); + } + 100% { + -ms-transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg); + } +} + +@-webkit-keyframes cssload-rotate-one { + 0% { + -webkit-transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg); + } + 100% { + -webkit-transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg); + } +} + +@-moz-keyframes cssload-rotate-one { + 0% { + -moz-transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg); + } + 100% { + -moz-transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg); + } +} + +@keyframes cssload-rotate-two { + 0% { + transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg); + } + 100% { + transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg); + } +} + +@-o-keyframes cssload-rotate-two { + 0% { + -o-transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg); + } + 100% { + -o-transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg); + } +} + +@-ms-keyframes cssload-rotate-two { + 0% { + -ms-transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg); + } + 100% { + -ms-transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg); + } +} + +@-webkit-keyframes cssload-rotate-two { + 0% { + -webkit-transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg); + } + 100% { + -webkit-transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg); + } +} + +@-moz-keyframes cssload-rotate-two { + 0% { + -moz-transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg); + } + 100% { + -moz-transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg); + } +} + +@keyframes cssload-rotate-three { + 0% { + transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg); + } + 100% { + transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg); + } +} + +@-o-keyframes cssload-rotate-three { + 0% { + -o-transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg); + } + 100% { + -o-transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg); + } +} + +@-ms-keyframes cssload-rotate-three { + 0% { + -ms-transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg); + } + 100% { + -ms-transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg); + } +} + +@-webkit-keyframes cssload-rotate-three { + 0% { + -webkit-transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg); + } + 100% { + -webkit-transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg); + } +} + +@-moz-keyframes cssload-rotate-three { + 0% { + -moz-transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg); + } + 100% { + -moz-transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg); + } +} \ No newline at end of file diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/dots/dots.component.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/components/dots/dots.component.spec.ts new file mode 100644 index 00000000..53e7d064 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/dots/dots.component.spec.ts @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2017-2024 Stefano Cappa (Ks89) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DebugElement } from '@angular/core'; +import { By } from '@angular/platform-browser'; + +import { DotsComponent } from './dots.component'; +import { AccessibilityConfig } from '../../model/accessibility.interface'; +import { DotsConfig } from '../../model/dots-config.interface'; +import { KS_DEFAULT_ACCESSIBILITY_CONFIG } from '../../components/accessibility-default'; +import { InternalLibImage } from '../../model/image-internal.class'; +import { ConfigService } from '../../services/config.service'; +import { AccessibleComponent } from '../accessible.component'; + +let comp: DotsComponent; +let fixture: ComponentFixture; +const GALLERY_ID = 1; + +const CUSTOM_ACCESSIBILITY: AccessibilityConfig = Object.assign({}, KS_DEFAULT_ACCESSIBILITY_CONFIG); +CUSTOM_ACCESSIBILITY.dotsContainerTitle = 'custom dotsContainerTitle'; +CUSTOM_ACCESSIBILITY.dotsContainerAriaLabel = 'custom dotsContainerAriaLabel'; + +const DOTS_CONFIG_VISIBLE: DotsConfig = {visible: true}; +const DOTS_CONFIG_HIDDEN: DotsConfig = {visible: false}; + +const IMAGES: InternalLibImage[] = [ + new InternalLibImage(0, { + // modal + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new InternalLibImage(1, { + // modal + img: '../assets/images/gallery/img2.png', + description: 'Description 2' + }), + new InternalLibImage( + 2, + { + // modal + img: '../assets/images/gallery/img3.jpg', + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + // plain + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new InternalLibImage(3, { + // modal + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new InternalLibImage( + 4, + { + // modal + img: '../assets/images/gallery/img5.jpg' + }, + { + // plain + img: '../assets/images/gallery/thumbs/img5.jpg' + } + ) +]; + +function initTestBed(): void { + TestBed.configureTestingModule({ + declarations: [DotsComponent, AccessibleComponent] + }).overrideComponent(DotsComponent, { + set: { + providers: [ + { + provide: ConfigService, + useClass: ConfigService + } + ] + } + }); +} + +describe('DotsComponent', () => { + beforeEach(() => { + initTestBed(); + fixture = TestBed.createComponent(DotsComponent); + comp = fixture.componentInstance; + }); + + it('should instantiate it', () => expect(comp).not.toBeNull()); + + describe('---YES---', () => { + + it(`should display dots (first one is active) based of the number of input images`, () => { + const activeDotIndex = 0; + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + dotsConfig: DOTS_CONFIG_VISIBLE, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[activeDotIndex]; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const dotsContainer: DebugElement = element.query(By.css('nav.dots-container')); + expect(dotsContainer.name).toBe('nav'); + expect(dotsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.dotsContainerAriaLabel); + expect(dotsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.dotsContainerTitle); + + const dots: DebugElement[] = dotsContainer.children; + expect(dots.length).toBe(IMAGES.length); + + dots.forEach((dot: DebugElement, index: number) => { + expect(dot.name).toBe('div'); + expect(dot.attributes.role).toBe('navigation'); + expect(dot.properties.tabIndex).toBe(0); + if (index === activeDotIndex) { + // I don't know why, but with dot.attributes.class I can't see 'active'. In this way it's working! + expect(dot.classes).toEqual({inside: true, dot: true, active: true}); + } else { + expect(dot.attributes.class).toBe('inside dot'); + // or like above: expect(dot.classes).toEqual({'inside': true, 'dot': true}); + } + expect(dot.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.dotAriaLabel + ' ' + (index + 1)); + }); + }); + + it(`should display dots (first one is active), because by default dotsConfig are visible`, () => { + const activeDotIndex = 0; + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + dotsConfig: undefined, // or null, or something not valid + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[activeDotIndex]; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const dotsContainer: DebugElement = element.query(By.css('nav.dots-container')); + expect(dotsContainer.name).toBe('nav'); + expect(dotsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.dotsContainerAriaLabel); + expect(dotsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.dotsContainerTitle); + + const dots: DebugElement[] = dotsContainer.children; + expect(dots.length).toBe(IMAGES.length); + + dots.forEach((dot: DebugElement, index: number) => { + expect(dot.name).toBe('div'); + expect(dot.attributes.role).toBe('navigation'); + expect(dot.properties.tabIndex).toBe(0); + + if (index === activeDotIndex) { + // I don't know why, but with dot.attributes.class I can't see 'active'. In this way it's working! + expect(dot.classes).toEqual({inside: true, dot: true, active: true}); + } else { + expect(dot.attributes.class).toBe('inside dot'); + // or like above: expect(dot.classes).toEqual({'inside': true, 'dot': true}); + } + expect(dot.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.dotAriaLabel + ' ' + (index + 1)); + }); + }); + + it(`should display dots (first one is active) with custom accessibility`, () => { + const activeDotIndex = 0; + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + dotsConfig: DOTS_CONFIG_VISIBLE, + accessibilityConfig: CUSTOM_ACCESSIBILITY + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[activeDotIndex]; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const dotsContainer: DebugElement = element.query(By.css('nav.dots-container')); + expect(dotsContainer.name).toBe('nav'); + expect(dotsContainer.attributes['aria-label']).toBe(CUSTOM_ACCESSIBILITY.dotsContainerAriaLabel); + expect(dotsContainer.properties.title).toBe(CUSTOM_ACCESSIBILITY.dotsContainerTitle); + + const dots: DebugElement[] = dotsContainer.children; + expect(dots.length).toBe(IMAGES.length); + + dots.forEach((dot: DebugElement, index: number) => { + expect(dot.name).toBe('div'); + expect(dot.attributes.role).toBe('navigation'); + expect(dot.properties.tabIndex).toBe(0); + + if (index === activeDotIndex) { + // I don't know why, but with dot.attributes.class I can't see 'active'. In this way it's working! + expect(dot.classes).toEqual({inside: true, dot: true, active: true}); + } else { + expect(dot.attributes.class).toBe('inside dot'); + // or like above: expect(dot.classes).toEqual({'inside': true, 'dot': true}); + } + expect(dot.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.dotAriaLabel + ' ' + (index + 1)); + }); + }); + + it(`should display dots and click on one of themem`, () => { + const indexToClick = 1; + const activeDotIndex = 0; + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + dotsConfig: DOTS_CONFIG_VISIBLE, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[activeDotIndex]; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + comp.clickDot.subscribe((index: number) => { + expect(index).toBe(indexToClick); + }, () => fail('after a click I should receive a clickDot event')); + + const dotsContainer: DebugElement = element.query(By.css('nav.dots-container')); + expect(dotsContainer).not.toBeNull(); + const dots: DebugElement[] = dotsContainer.children; + expect(dots.length).toBe(IMAGES.length); + + // clicks on a dot + dots[1].nativeElement.click(); + }); + }); + + describe('---NO---', () => { + + it(`shouldn't display dots, because visibility is false.`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + dotsConfig: DOTS_CONFIG_VISIBLE, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + comp.id = GALLERY_ID; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const dotsContainer: DebugElement = element.query(By.css('nav.dots-container')); + expect(dotsContainer.name).toBe('nav'); + expect(dotsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.dotsContainerAriaLabel); + expect(dotsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.dotsContainerTitle); + + const dots: DebugElement[] = element.queryAll(By.css('div.inside.dot')); + expect(dots.length).toBe(0); + }); + + it(`shouldn't display dots, because the array of images as input is empty`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = undefined; + comp.images = []; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const dotsContainer: DebugElement = element.query(By.css('nav.dots-container')); + expect(dotsContainer.name).toBe('nav'); + expect(dotsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.dotsContainerAriaLabel); + expect(dotsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.dotsContainerTitle); + + const dots: DebugElement[] = dotsContainer.children; + expect(dots.length).toBe(0); + }); + + it(`shouldn't display dots, because the array of images as input is not valid`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = undefined; + comp.images = undefined; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const dotsContainer: DebugElement = element.query(By.css('nav.dots-container')); + expect(dotsContainer.name).toBe('nav'); + expect(dotsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.dotsContainerAriaLabel); + expect(dotsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.dotsContainerTitle); + + const dots: DebugElement[] = dotsContainer.children; + expect(dots.length).toBe(0); + }); + + it(`shouldn't display active dot when the currentImage is invalid, because 'isActive' method throws a managed error and return false`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG + }); + comp.id = GALLERY_ID; + // create a fake image not available in comp.images array + comp.currentImage = new InternalLibImage(99, IMAGES[0].modal); + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const dotsContainer: DebugElement = element.query(By.css('nav.dots-container')); + expect(dotsContainer.name).toBe('nav'); + expect(dotsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.dotsContainerAriaLabel); + expect(dotsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.dotsContainerTitle); + + const dots: DebugElement[] = dotsContainer.children; + expect(dots.length).toBe(IMAGES.length); + + // all dots are NOT active, bat simply 'inside dot' + dots.forEach((dot: DebugElement, index: number) => { + expect(dot.name).toBe('div'); + expect(dot.attributes.role).toBe('navigation'); + expect(dot.properties.tabIndex).toBe(0); + expect(dot.attributes.class).toBe('inside dot'); + expect(dot.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.dotAriaLabel + ' ' + (index + 1)); + }); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/dots/dots.component.ts b/projects/ks89/angular-modal-gallery/src/lib/components/dots/dots.component.ts new file mode 100644 index 00000000..7abf8e62 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/dots/dots.component.ts @@ -0,0 +1,161 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChange, SimpleChanges } from '@angular/core'; + +import { AccessibleComponent } from '../accessible.component'; + +import { AccessibilityConfig } from '../../model/accessibility.interface'; +import { Image } from '../../model/image.class'; +import { InternalLibImage } from '../../model/image-internal.class'; +import { DotsConfig } from '../../model/dots-config.interface'; + +import { NEXT } from '../../utils/user-input.util'; +import { getIndex } from '../../utils/image.util'; +import { ConfigService } from '../../services/config.service'; +import { LibConfig } from '../../model/lib-config.interface'; + +/** + * Component with clickable dots (small circles) to navigate between images inside the modal gallery. + */ +@Component({ + selector: 'ks-dots', + styleUrls: ['dots.scss'], + templateUrl: 'dots.html', + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: false +}) +export class DotsComponent extends AccessibleComponent implements OnInit, OnChanges { + /** + * Unique id (>=0) of the current instance of this library. This is required when you are using + * the service to call modal gallery. + */ + @Input() + id!: number + /** + * Object of type `InternalLibImage` that represent the visible image. + */ + @Input() + currentImage: InternalLibImage | undefined + /** + * Array of `InternalLibImage` that represent the model of this library with all images, + * thumbs and so on. + */ + @Input() + images: InternalLibImage[] | undefined; + /** + * Object of type `DotsConfig` to init DotsComponent's features. + * For instance, it contains a param to show/hide this component. + */ + @Input() + dotsConfig!: DotsConfig; + + /** + * Output to emit clicks on dots. The payload contains a number that represent + * the index of the clicked dot. + */ + @Output() + clickDot: EventEmitter = new EventEmitter(); + + /** + * Object of type `DotsConfig` used in template. + */ + configDots: DotsConfig | undefined; + /** + * Object of type `AccessibilityConfig` to init custom accessibility features. + * For instance, it contains titles, alt texts, aria-labels and so on. + */ + accessibilityConfig: AccessibilityConfig | undefined; + + constructor(private configService: ConfigService) { + super(); + } + + /** + * Method ´ngOnInit´ to build `configDots` applying a default value. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called only one time!!! + */ + ngOnInit(): void { + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + this.accessibilityConfig = libConfig.accessibilityConfig; + this.configDots = Object.assign({}, this.dotsConfig); + } + + /** + * Method ´ngOnChanges´ to change `configDots` if the input dotsConfig is changed. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + */ + ngOnChanges(changes: SimpleChanges): void { + const dotsConfigChanges: SimpleChange = changes.dotsConfig; + if (dotsConfigChanges && dotsConfigChanges.currentValue !== dotsConfigChanges.previousValue) { + this.configDots = dotsConfigChanges.currentValue; + } + } + + /** + * Method to check if an image is active (i.e. the current image). + * It checks currentImage and images to prevent errors. + * @param number index of the image to check if it's active or not + * @returns boolean true if is active (and input params are valid), false otherwise + */ + isActive(index: number): boolean { + if (!this.currentImage || !this.images || this.images.length === 0) { + return false; + } + let imageIndex: number; + try { + imageIndex = getIndex(this.currentImage, this.images); + } catch (err) { + console.error(`Internal error while trying to show the active 'dot'`, err); + return false; + } + return index === imageIndex; + } + + /** + * Method called by events from keyboard and mouse. + * @param number index of the dot + * @param KeyboardEvent | MouseEvent event payload + */ + onDotEvent(index: number, event: KeyboardEvent | MouseEvent): void { + const result: number = super.handleImageEvent(event); + if (result === NEXT) { + this.clickDot.emit(index); + } + } + + /** + * Method used in the template to track ids in ngFor. + * @param number index of the array + * @param Image item of the array + * @returns number the id of the item + */ + trackById(index: number, item: Image): number { + return item.id; + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/dots/dots.html b/projects/ks89/angular-modal-gallery/src/lib/components/dots/dots.html new file mode 100644 index 00000000..6666d48d --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/dots/dots.html @@ -0,0 +1,11 @@ + diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/dots/dots.scss b/projects/ks89/angular-modal-gallery/src/lib/components/dots/dots.scss new file mode 100644 index 00000000..12e3ba9f --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/dots/dots.scss @@ -0,0 +1,85 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +$container-margin-bottom: 30px; +$dot-color: #fff; +$dot-width: 10px; +$dot-height: 10px; +$dot-radius: 5px; +$dot-side-margin: 4px; +$dot-opacity: .5; +$dot-hover-opacity: .9; +$dot-active-opacity: .9; +$fade-in-time: .8s; + +@mixin dot($color, $width, $height, $side-margin, $radius) { + background: $color; + border-radius: $radius; + height: $height; + margin-left: $side-margin; + margin-right: $side-margin; + width: $width; +} + +.dots-container { + display: flex; + flex-direction: row; + justify-content: center; + margin-bottom: $container-margin-bottom; + + > .dot { + @include dot($dot-color, $dot-width, $dot-height, $dot-side-margin, $dot-radius); + + //animation: fadein-semi-visible05 $fade-in-time; + cursor: pointer; + opacity: $dot-opacity; + + &:hover { + opacity: $dot-hover-opacity; + transition: all .5s ease; + transition-property: opacity; + } + + &.active { + //animation: fadein-semi-visible09 $fade-in-time; + cursor: pointer; + opacity: $dot-active-opacity; + } + } +} + +@mixin fadein($opacity-from, $opacity-to) { + from { + opacity: $opacity-from; + } + to { + opacity: $opacity-to; + } +} + +@keyframes fadein-semi-visible05 { + @include fadein(0, .5); +} + +@keyframes fadein-semi-visible09 { + @include fadein(0, .9); +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/image-arrows.scss b/projects/ks89/angular-modal-gallery/src/lib/components/image-arrows.scss new file mode 100644 index 00000000..6dba6ceb --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/image-arrows.scss @@ -0,0 +1,64 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// all svgs are converted to base 64 with this website http://b64.io/ + +$arrow-image-width: 30px; +$arrow-image-height: 30px; +$arrow-image-bg-size: 30px; +$arrow-image-transition: .5s; +$arrow-image-scale: 1.2; +$arrow-image-opacity: .8; + +.arrow-image { + width: $arrow-image-width; + height: $arrow-image-height; + background-size: $arrow-image-bg-size; +} + +.empty-arrow-image { + @extend .arrow-image; + background: black; + opacity: 0; +} + +.left-arrow-image { + @extend .arrow-image; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ3Ny4xNzUgNDc3LjE3NSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDc3LjE3NSA0NzcuMTc1OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij48Zz48cGF0aCBkPSJNMTQ1LjE4OCwyMzguNTc1bDIxNS41LTIxNS41YzUuMy01LjMsNS4zLTEzLjgsMC0xOS4xcy0xMy44LTUuMy0xOS4xLDBsLTIyNS4xLDIyNS4xYy01LjMsNS4zLTUuMywxMy44LDAsMTkuMWwyMjUuMSwyMjUgICBjMi42LDIuNiw2LjEsNCw5LjUsNHM2LjktMS4zLDkuNS00YzUuMy01LjMsNS4zLTEzLjgsMC0xOS4xTDE0NS4xODgsMjM4LjU3NXoiIGZpbGw9IiNGRkZGRkYiLz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+"); + opacity: $arrow-image-opacity; + transition: all $arrow-image-transition; + + &:hover { + transform: scale($arrow-image-scale); + } +} + +.right-arrow-image { + @extend .arrow-image; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ3Ny4xNzUgNDc3LjE3NSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDc3LjE3NSA0NzcuMTc1OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij48Zz48cGF0aCBkPSJNMzYwLjczMSwyMjkuMDc1bC0yMjUuMS0yMjUuMWMtNS4zLTUuMy0xMy44LTUuMy0xOS4xLDBzLTUuMywxMy44LDAsMTkuMWwyMTUuNSwyMTUuNWwtMjE1LjUsMjE1LjUgICBjLTUuMyw1LjMtNS4zLDEzLjgsMCwxOS4xYzIuNiwyLjYsNi4xLDQsOS41LDRjMy40LDAsNi45LTEuMyw5LjUtNGwyMjUuMS0yMjUuMUMzNjUuOTMxLDI0Mi44NzUsMzY1LjkzMSwyMzQuMjc1LDM2MC43MzEsMjI5LjA3NXogICAiIGZpbGw9IiNGRkZGRkYiLz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+"); + opacity: $arrow-image-opacity; + transition: all $arrow-image-transition; + + &:hover { + transform: scale($arrow-image-scale); + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/attach-to-overlay.service.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/attach-to-overlay.service.spec.ts new file mode 100644 index 00000000..f69c025d --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/attach-to-overlay.service.spec.ts @@ -0,0 +1,117 @@ +import { inject, TestBed, waitForAsync } from '@angular/core/testing'; +import { AttachToOverlayService } from './attach-to-overlay.service'; +import { ModalGalleryService } from './modal-gallery.service'; +import { OverlayModule, OverlayRef } from "@angular/cdk/overlay"; +import { Image } from '../../model/image.class'; +import { ModalGalleryRef } from './modal-gallery-ref'; +import { ModalGalleryComponent } from './modal-gallery.component'; +import { UpperButtonsComponent } from '../upper-buttons/upper-buttons.component'; +import { CurrentImageComponent } from '../current-image/current-image.component'; +import { DotsComponent } from '../dots/dots.component'; +import { PreviewsComponent } from '../previews/previews.component'; + +const IMAGES: Image[] = [ + new Image(0, { + // modal + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new Image(1, { + // modal + img: '../assets/images/gallery/img2.png', + description: 'Description 2' + }), + new Image( + 2, + { + // modal + img: '../assets/images/gallery/img3.jpg', + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + // plain + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new Image(3, { + // modal + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new Image( + 4, + { + // modal + img: '../assets/images/gallery/img5.jpg' + }, + { + // plain + img: '../assets/images/gallery/thumbs/img5.jpg' + } + ) +]; + +describe('AttachToOverlayService', () => { + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [OverlayModule], + declarations: [ModalGalleryComponent, UpperButtonsComponent, + CurrentImageComponent, DotsComponent, PreviewsComponent + ], + providers: [ + AttachToOverlayService, + { + provide: ModalGalleryService, + useClass: ModalGalleryService + } + ] + }); + })); + + it('should instantiate service when inject service', inject([AttachToOverlayService], (service: AttachToOverlayService) => { + expect(service instanceof AttachToOverlayService).toEqual(true); + })); + + describe('#attachToOverlay()', () => { + describe('---YES---', () => { + it('should call the attach method on the given overlayRef', inject( + [ModalGalleryService, AttachToOverlayService], + (modalGalleryService: ModalGalleryService, attachToOverlayService: AttachToOverlayService) => { + attachToOverlayService.initialize(); + const ID: number = 1; + const config = { + id: ID, + images: IMAGES, + currentImage: IMAGES[0] + }; + const ref: ModalGalleryRef | undefined = modalGalleryService.open({ + id: ID, + images: IMAGES, + currentImage: IMAGES[0] + }); + expect(ref).toBeDefined(); + expect(ref instanceof ModalGalleryRef).toBeTrue(); + let attachCalled = false; + const mockOverlayRef = { + attach: () => { + attachCalled = true; + } + }; + + modalGalleryService.triggerAttachToOverlay.emit({ + config, + dialogRef: ref as ModalGalleryRef, + overlayRef: mockOverlayRef as unknown as OverlayRef + }); + + expect(attachCalled).toBeTrue(); + } + )); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/attach-to-overlay.service.ts b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/attach-to-overlay.service.ts new file mode 100644 index 00000000..efbfb666 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/attach-to-overlay.service.ts @@ -0,0 +1,36 @@ +import { Injectable, Injector } from '@angular/core'; +import { ModalGalleryRef } from './modal-gallery-ref'; +import { ModalGalleryComponent } from './modal-gallery.component'; +import { DIALOG_DATA } from './modal-gallery.tokens'; +import { ComponentPortal } from '@angular/cdk/portal'; +import { AttachToOverlayPayload, ModalGalleryService } from './modal-gallery.service'; + +@Injectable({ providedIn: 'root' }) +export class AttachToOverlayService { + constructor(private injector: Injector, private modalGalleryService: ModalGalleryService) {} + + /** + * To be called by a provider with the APP_INITIALIZER token. + */ + public initialize(): void { + this.modalGalleryService.triggerAttachToOverlay.subscribe(payload => this.attachToOverlay(payload)); + } + + /** + * Private method to attach ModalGalleryComponent to the overlay. + * @param payload {@link AttachToOverlayPayload} with all necessary information + * @private + */ + private attachToOverlay(payload: AttachToOverlayPayload): void { + const injector: Injector = Injector.create({ + parent: this.injector, + providers: [ + { provide: ModalGalleryRef, useValue: payload.dialogRef }, + { provide: DIALOG_DATA, useValue: payload.config } + ] + }); + + const containerPortal = new ComponentPortal(ModalGalleryComponent, null, injector); + payload.overlayRef.attach(containerPortal); + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery-ref.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery-ref.spec.ts new file mode 100644 index 00000000..99bb0903 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery-ref.spec.ts @@ -0,0 +1,169 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { inject, waitForAsync } from '@angular/core/testing'; +import { OverlayRef } from '@angular/cdk/overlay'; + +import { ModalGalleryRef } from './modal-gallery-ref'; +import { Image, ImageModalEvent } from '../../model/image.class'; +import { Action } from '../../model/action.enum'; +import { ButtonConfig, ButtonEvent, ButtonType } from '../../model/buttons-config.interface'; +import { InternalLibImage } from '../../model/image-internal.class'; + +const IMAGES: Image[] = [ + new Image(0, { + // modal + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new Image(1, { + // modal + img: '../assets/images/gallery/img2.png', + description: 'Description 2' + }), + new Image( + 2, + { + // modal + img: '../assets/images/gallery/img3.jpg', + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + // plain + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new Image(3, { + // modal + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new Image( + 4, + { + // modal + img: '../assets/images/gallery/img5.jpg' + }, + { + // plain + img: '../assets/images/gallery/thumbs/img5.jpg' + } + ) +]; + +const ID: number = 1; + +const EVENT: ImageModalEvent = new ImageModalEvent(ID, Action.NORMAL, true); + +const BTNEVENT: ButtonEvent = { + button: { + type: ButtonType.CLOSE + } as ButtonConfig, + image: IMAGES[ID] as InternalLibImage, + action: Action.NORMAL, + galleryId: ID +}; + +class OverlayRefMock { + dispose() { + } +} + +let ref: ModalGalleryRef = new ModalGalleryRef(new OverlayRefMock() as OverlayRef); + +describe('ModalGalleryRef', () => { + describe('#closeModal()', () => { + it(`should call closeModal`, () => { + ref.closeModal(); + }); + }); + + describe('#emitClose()', () => { + it(`should call emitClose`, () => { + ref.close$.subscribe((event: ImageModalEvent) => { + expect(EVENT).toEqual(event); + }); + ref.emitClose(EVENT); + }); + }); + + describe('#emitShow()', () => { + it(`should call emitShow`, () => { + ref.show$.subscribe((event: ImageModalEvent) => { + expect(EVENT).toEqual(event); + }); + ref.emitShow(EVENT); + }); + }); + + describe('#emitFirstImage()', () => { + it(`should call emitFirstImage`, () => { + ref.firstImage$.subscribe((event: ImageModalEvent) => { + expect(EVENT).toEqual(event); + }); + ref.emitFirstImage(EVENT); + }); + }); + + describe('#emitLastImage()', () => { + it(`should call emitLastImage`, () => { + ref.lastImage$.subscribe((event: ImageModalEvent) => { + expect(EVENT).toEqual(event); + }); + ref.emitLastImage(EVENT); + }); + }); + + describe('#emitHasData()', () => { + it(`should call emitHasData`, () => { + ref.hasData$.subscribe((event: ImageModalEvent) => { + expect(EVENT).toEqual(event); + }); + ref.emitHasData(EVENT); + }); + }); + + describe('#emitButtonBeforeHook()', () => { + it(`should call emitButtonBeforeHook`, () => { + ref.buttonBeforeHook$.subscribe((event: ButtonEvent) => { + expect(BTNEVENT).toEqual(event); + }); + ref.emitButtonBeforeHook(BTNEVENT); + }); + }); + + describe('#emitButtonAfterHook()', () => { + it(`should call emitButtonAfterHook`, () => { + ref.buttonAfterHook$.subscribe((event: ButtonEvent) => { + expect(BTNEVENT).toEqual(event); + }); + ref.emitButtonAfterHook(BTNEVENT); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery-ref.ts b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery-ref.ts new file mode 100644 index 00000000..0cfdc34a --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery-ref.ts @@ -0,0 +1,115 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { OverlayRef } from '@angular/cdk/overlay'; + +import { Subject } from 'rxjs'; +import { ImageModalEvent } from '../../model/image.class'; +import { ButtonEvent } from '../../model/buttons-config.interface'; + +/** + * Class that represents the modal dialog instance. + * It is returned by the open method. + */ +export class ModalGalleryRef { + private close = new Subject(); + close$ = this.close.asObservable(); + private show = new Subject(); + show$ = this.show.asObservable(); + private firstImage = new Subject(); + firstImage$ = this.firstImage.asObservable(); + private lastImage = new Subject(); + lastImage$ = this.lastImage.asObservable(); + private hasData = new Subject(); + hasData$ = this.hasData.asObservable(); + private buttonBeforeHook = new Subject(); + buttonBeforeHook$ = this.buttonBeforeHook.asObservable(); + private buttonAfterHook = new Subject(); + buttonAfterHook$ = this.buttonAfterHook.asObservable(); + + constructor(private overlayRef: OverlayRef) {} + + /** + * Close modal dialog, disposing the Overlay. + */ + closeModal(): void { + this.overlayRef.dispose(); + } + + /** + * Method to emit close event. + * @param event ImageModalEvent event payload + */ + emitClose(event: ImageModalEvent): void { + this.close.next(event); + } + + /** + * Method to emit show event. + * @param event ImageModalEvent event payload + */ + emitShow(event: ImageModalEvent): void { + this.show.next(event); + } + + /** + * Method to emit firstImage event. + * @param event ImageModalEvent event payload + */ + emitFirstImage(event: ImageModalEvent): void { + this.firstImage.next(event); + } + + /** + * Method to emit lastImage event. + * @param event ImageModalEvent event payload + */ + emitLastImage(event: ImageModalEvent): void { + this.lastImage.next(event); + } + + /** + * Method to emit hasData event. + * @param event ImageModalEvent event payload + */ + emitHasData(event: ImageModalEvent): void { + this.hasData.next(event); + } + + /** + * Method to emit buttonBeforeHook event. + * @param event ImageModalEvent event payload + */ + emitButtonBeforeHook(event: ButtonEvent): void { + this.buttonBeforeHook.next(event); + } + + /** + * Method to emit buttonAfterHook event. + * @param event ImageModalEvent event payload + */ + emitButtonAfterHook(event: ButtonEvent): void { + this.buttonAfterHook.next(event); + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.component.html b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.component.html new file mode 100644 index 00000000..0dcbbb08 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.component.html @@ -0,0 +1,42 @@ + diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.component.scss b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.component.scss new file mode 100644 index 00000000..ef4c0e9c --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.component.scss @@ -0,0 +1,39 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// Workaround for IE 10/11 documented here +// https://github.com/philipwalton/flexbugs#workaround-2 +// also with live examples on codepen +#flex-min-height-ie-fix { + display: flex; + flex-direction: column; + justify-content: center; +} + +#modal-gallery-container { + display: flex; + flex-direction: column; + justify-content: space-between; + min-width: 100vw; + // min-height: 100vh is a part of the workaround https://github.com/philipwalton/flexbugs#workaround-2 + min-height: 100vh; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.component.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.component.spec.ts new file mode 100644 index 00000000..1a08b2d7 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.component.spec.ts @@ -0,0 +1,802 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import Spy = jasmine.Spy; + +import { DebugElement } from '@angular/core'; + +import { AccessibilityConfig } from '../../model/accessibility.interface'; +import { KS_DEFAULT_ACCESSIBILITY_CONFIG } from '../../components/accessibility-default'; +import { InternalLibImage } from '../../model/image-internal.class'; +import { ModalGalleryComponent } from './modal-gallery.component'; +import { Size } from '../../model/size.interface'; +import { SizeDirective } from '../../directives/size.directive'; +import { WrapDirective } from '../../directives/wrap.directive'; +import { DirectionDirective } from '../../directives/direction.directive'; +import { ATagBgImageDirective } from '../../directives/a-tag-bg-image.directive'; +import { ConfigService } from '../../services/config.service'; +import { ModalGalleryService } from './modal-gallery.service'; +import { IdValidatorService } from '../../services/id-validator.service'; +import { ModalGalleryConfig } from '../../model/modal-gallery-config.interface'; +import { DIALOG_DATA } from './modal-gallery.tokens'; +import { OverlayModule } from '@angular/cdk/overlay'; +import { LibConfig } from '../../model/lib-config.interface'; +import { UpperButtonsComponent } from '../upper-buttons/upper-buttons.component'; +import { CurrentImageComponent, ImageLoadEvent } from '../current-image/current-image.component'; +import { DotsComponent } from '../dots/dots.component'; +import { PreviewsComponent } from '../previews/previews.component'; +import { FallbackImageDirective } from '../../directives/fallback-image.directive'; +import { ClickOutsideDirective } from '../../directives/click-outside.directive'; +import { LoadingSpinnerComponent } from '../current-image/loading-spinner/loading-spinner.component'; +import { DescriptionDirective } from '../../directives/description.directive'; +import { KeyboardNavigationDirective } from '../../directives/keyboard-navigation.directive'; +import { By, DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; +import { ButtonConfig, ButtonEvent, ButtonType } from '../../model/buttons-config.interface'; +import { Action } from '../../model/action.enum'; +import { ImageModalEvent } from '../../model/image.class'; +import { CurrentImageConfig } from '../../model/current-image-config.interface'; + +let comp: ModalGalleryComponent; +let fixture: ComponentFixture; + +const CUSTOM_ACCESSIBILITY: AccessibilityConfig = Object.assign({}, KS_DEFAULT_ACCESSIBILITY_CONFIG); +CUSTOM_ACCESSIBILITY.plainGalleryContentAriaLabel = 'custom plainGalleryContentAriaLabel'; +CUSTOM_ACCESSIBILITY.plainGalleryContentTitle = 'custom plainGalleryContentTitle'; + +const DEFAULT_PLAIN_SIZE: Size = { width: 'auto', height: '50px' }; +const CUSTOM_SIZE: Size = { height: '40px', width: '40px' }; +const CUSTOM_SIZE_AUTO_HEIGHT: Size = { height: 'auto', width: '40px' }; +const CUSTOM_SIZE_AUTO_WIDTH: Size = { height: '40px', width: 'auto' }; +const CUSTOM_SIZES: Size[] = [CUSTOM_SIZE, CUSTOM_SIZE_AUTO_HEIGHT, CUSTOM_SIZE_AUTO_WIDTH]; + +const GALLERY_ID = 0; + +const IMAGES: InternalLibImage[] = [ + new InternalLibImage(0, { + // modal + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new InternalLibImage(1, { + // modal + img: '../assets/images/gallery/img2.png', + description: 'Description 2' + }), + new InternalLibImage( + 2, + { + // modal + img: '../assets/images/gallery/img3.jpg', + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + // plain + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new InternalLibImage(3, { + // modal + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new InternalLibImage( + 4, + { + // modal + img: '../assets/images/gallery/img5.jpg' + }, + { + // plain + img: '../assets/images/gallery/thumbs/img5.jpg' + } + ) +]; + +const IMAGES_CUSTOM_DOWNLOAD_FILENAME: InternalLibImage[] = [ + new InternalLibImage(0, { + // modal + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com', + downloadFileName: 'a.png' + }), + new InternalLibImage(1, { + // modal + img: '../assets/images/gallery/img2.png', + description: 'Description 2', + downloadFileName: 'b.png' + }) +]; + +// example of a png converted into base64 using https://www.base64-image.de/ or other similar websites +const base64String = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABN0lEQV' + + 'R4nO3SQQ2AQBDAwAVlaMEhCkAV' + + 'b2RcQmcU9NEZAAAAAOD/tvN675k5VoewxLOvLmAtA8QZIM4AcQaIM0CcAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4gwQZ4A4A8QZIM4AcQaIM0C' + + 'cAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4gwQZ4A4A8QZIM4AcQaIM0CcAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4g' + + 'wQZ4A4A8QZIM4AcQaIM0CcAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4gwQZ4A4A8QZIM4AcQaIM0CcAeIMEGeAOAPEGQAAAAAA4Pc+8asEoPPGq' + + 'xUAAAAASUVORK5CYII'; + +const base64RedString = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAY1BMVEX/AAD/////WVn/+vr/qan/Nzf/ERH/2tr/s7P/KSn/' + + '7+//vr7/0ND/W1v/6+v/m5v/4+P/U1P/HR3/o6P/rq7/g4P/k5P/t7f/dXX/SEj/zMz/ZWX/h4f/bm7/amr/np7/yMhDG/2oAAAC8ElEQVR4nO3dC3KqQBCF4WkHERHFRyKIL/' + + 'a/ymDuVYMMFipTbbfnW8H5S4lQVGUMaWe4B3iHQvlQKB8K5UOhfCiUD4XyoVA+FJ7Myijd5dvBO9nmuzQqZ68X2mI9NO9suC7s84VxNuAO6GSQxU8VJvuQe3pn4T55uLDYcK9+' + + '0KZ4qDB574vPbej+HF2Fcc499km563p0FAbcQ18QdCi0B+6VLzk0fjtuC0dj7o0vGo/uF064B/agvFcYca/rRdReeOTe1pNjW6HkP6J1gbtQwzV4NnEVJtyrepU0C2M599ldhH' + + 'GjcMq9qWfT28KUe1Hv0nrhnHuPB/Na4YJ7jgeLv4UZ9xovsmuhXXKP8WJpL4Ur7i2erC6Fun4Kr8Jz4Rf3Em++/hdKf+htN/5XqOuGtC75LfzmnuHR96nQ6v2SVl9TWxVq/pKevq' + + 'aG1twjvFpXhTLeLz1rQMZyb/DMmhH3BM9GRudjxVVmtN51n62M1DdpXeVG2rveR22MxLe9jxgazfdsJ2Oj9en3THsfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + + 'AAAAAAAAAAAAAAgHba/+98+AFnI+g/30L/GSX6z5nRf1aQ/vOe9J/Zpf/cNf1n533A+Yf6z7DUfw6p/rNkVX9Nkw850/kDzuXWf7Y6ab37Xl0K7ZJ7ixdLeykknQ8YGV0LacG9xo' + + 'MF/S2cc8/xYF4rpJR7T+9SqhfSlHtRz6Z0Wxjr+lEM40ahstvThJqFNOFe1aMJuQop4N7Vm4DchXTkXtaTI7UVUsS9rRcRtRequBZLuldII+mPw+MR3S8ke+De+JKDvQ1qFMr+kx' + + 'o0cxyFFEt945bHjhpXYXV/I/HN8DBxtrgLiQpp74Y3RUtJW2H1Oe7l3IuHe/fnd7+wuh4zGe+lBpnr+utSWLHF+r0vyeG6aPw+PFT4a1ZG6S7fDt7JNt+lUTnrsL5LoWwolA+F8q' + + 'FQPhTKh0L5UCgfCuVDoXw/lnQz7dm7GjoAAAAASUVORK5CYII='; +const base64GreenString = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAgMAAADQNkYNAAAADFBMVEUAAAAy/ysy/ysy/ysyTcibAAAAA3RSTlMA2r/af0d' + + 'WAAAAQUlEQVRo3u3YMREAMAzEsJAMyZJsMXy3XORdBFySJK3qxFXH1Y1DEARBEARBEARBEARBEARBkNmk436mvSRJ0o4eOKL2P81eyn8AAAAASUVORK5CYII='; + +function initTestBed(): void { + TestBed.configureTestingModule({ + imports: [OverlayModule], + declarations: [ModalGalleryComponent, + UpperButtonsComponent, CurrentImageComponent, DotsComponent, PreviewsComponent, LoadingSpinnerComponent, + FallbackImageDirective, ClickOutsideDirective, DescriptionDirective, KeyboardNavigationDirective, + SizeDirective, WrapDirective, DirectionDirective, ATagBgImageDirective] + }).overrideComponent(ModalGalleryComponent, { + set: { + providers: [ + { + provide: ConfigService, + useClass: ConfigService + }, + { + provide: ModalGalleryService, + useClass: ModalGalleryService + }, + { + provide: IdValidatorService, + useClass: IdValidatorService + }, + { + provide: DIALOG_DATA, + useValue: { + id: GALLERY_ID, + images: IMAGES, + currentImage: IMAGES[0], + libConfig: { + accessibilityConfig: CUSTOM_ACCESSIBILITY + } as LibConfig + } as ModalGalleryConfig + } + ] + } + }); +} + +function checkElements (fixture: ComponentFixture) { + const element: DebugElement = fixture.debugElement; + const modalGalleryWrapper: DebugElement = element.query(By.css('div#modal-gallery-wrapper')); + expect(modalGalleryWrapper).not.toBeNull(); + + const fixMinHeight: DebugElement = modalGalleryWrapper.children[0]; + const modalGalleryContainer: DebugElement = fixMinHeight.children[0]; + const list: DebugElement[] = modalGalleryContainer.children; + expect(list.length).toEqual(3); + + const buttonsContainer: DebugElement = modalGalleryContainer.query(By.css('header.buttons-container')); + const mainImageContainer: DebugElement = modalGalleryContainer.query(By.css('main.main-image-container')); + const dotsContainer: DebugElement = modalGalleryContainer.query(By.css('nav.dots-container')); + const previewsContainer: DebugElement = modalGalleryContainer.query(By.css('nav.previews-container')); + expect(buttonsContainer).not.toBeNull(); + expect(mainImageContainer).not.toBeNull(); + expect(dotsContainer).not.toBeNull(); + expect(previewsContainer).not.toBeNull(); +} + +describe('ModalGalleryComponent', () => { + beforeEach(() => { + initTestBed(); + fixture = TestBed.createComponent(ModalGalleryComponent); + comp = fixture.componentInstance; + }); + + it('should instantiate it', () => expect(comp).not.toBeNull()); + + describe('---YES---', () => { + + it(`should display modal gallery - first image`, (done) => { + const modalGalleryService = fixture.debugElement.injector.get(ModalGalleryService); + const configService = fixture.debugElement.injector.get(ConfigService); + + const hasDataSpy: Spy = spyOn(modalGalleryService, 'emitHasData'); + const showSpy: Spy = spyOn(modalGalleryService, 'emitShow'); + const firstImageSpy: Spy = spyOn(modalGalleryService, 'emitFirstImage'); + + configService.setConfig(GALLERY_ID, { accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + checkElements(fixture); + + setTimeout(() => { + expect(hasDataSpy).toHaveBeenCalled(); + expect(showSpy).toHaveBeenCalled(); + expect(firstImageSpy).toHaveBeenCalled(); + done(); + }, 500); + }); + + it(`should display modal gallery - last image`, (done) => { + const modalGalleryService = fixture.debugElement.injector.get(ModalGalleryService); + const configService = fixture.debugElement.injector.get(ConfigService); + + const hasDataSpy: Spy = spyOn(modalGalleryService, 'emitHasData'); + const showSpy: Spy = spyOn(modalGalleryService, 'emitShow'); + const lastImageSpy: Spy = spyOn(modalGalleryService, 'emitLastImage'); + + configService.setConfig(GALLERY_ID, { accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[IMAGES.length - 1]; + fixture.detectChanges(); + + checkElements(fixture); + + setTimeout(() => { + expect(hasDataSpy).toHaveBeenCalled(); + expect(showSpy).toHaveBeenCalled(); + expect(lastImageSpy).toHaveBeenCalled(); + done(); + }, 500); + }); + + it(`should display modal gallery and call onCustomEmit`, () => { + const modalGalleryService = fixture.debugElement.injector.get(ModalGalleryService); + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + checkElements(fixture); + + const beforeHookSpy: Spy = spyOn(modalGalleryService, 'emitButtonBeforeHook'); + const afterHookSpy: Spy = spyOn(modalGalleryService, 'emitButtonAfterHook'); + + const EVENT: ButtonEvent = { + button: { + type: ButtonType.CUSTOM + } as ButtonConfig, + image: IMAGES[0] as InternalLibImage, + action: Action.NORMAL, + galleryId: GALLERY_ID + }; + comp.onCustomEmit(EVENT); + + expect(beforeHookSpy).toHaveBeenCalled(); + expect(afterHookSpy).toHaveBeenCalled(); + }); + + it(`should display modal gallery and call onFullScreen`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, {accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG}); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + checkElements(fixture); + + const EVENT: ButtonEvent = { + button: { + type: ButtonType.FULLSCREEN + } as ButtonConfig, + image: IMAGES[0] as InternalLibImage, + action: Action.NORMAL, + galleryId: GALLERY_ID + }; + comp.onFullScreen(EVENT); + }); + + it(`should display modal gallery and call onDelete`, () => { + const modalGalleryService = fixture.debugElement.injector.get(ModalGalleryService); + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + checkElements(fixture); + + const beforeHookSpy: Spy = spyOn(modalGalleryService, 'emitButtonBeforeHook'); + const afterHookSpy: Spy = spyOn(modalGalleryService, 'emitButtonAfterHook'); + + const EVENT: ButtonEvent = { + button: { + type: ButtonType.DELETE + } as ButtonConfig, + image: IMAGES[0] as InternalLibImage, + action: Action.NORMAL, + galleryId: GALLERY_ID + }; + comp.onDelete(EVENT); + + expect(beforeHookSpy).toHaveBeenCalled(); + expect(afterHookSpy).toHaveBeenCalled(); + }); + + it(`should display modal gallery and call onDelete with only 1 image`, () => { + const modalGalleryService = fixture.debugElement.injector.get(ModalGalleryService); + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG }); + comp.id = GALLERY_ID; + comp.images = [IMAGES[0]]; // only 1 image + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + checkElements(fixture); + + const beforeHookSpy: Spy = spyOn(modalGalleryService, 'emitButtonBeforeHook'); + const afterHookSpy: Spy = spyOn(modalGalleryService, 'emitButtonAfterHook'); + const emitCloseSpy: Spy = spyOn(modalGalleryService, 'emitClose'); + + const EVENT: ButtonEvent = { + button: { + type: ButtonType.DELETE + } as ButtonConfig, + image: IMAGES[0] as InternalLibImage, + action: Action.NORMAL, + galleryId: GALLERY_ID + }; + comp.onDelete(EVENT); + + expect(beforeHookSpy).toHaveBeenCalled(); + expect(afterHookSpy).toHaveBeenCalled(); + expect(emitCloseSpy).toHaveBeenCalled(); + }); + + it(`should display modal gallery and call onNavigate`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, {accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG}); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + checkElements(fixture); + + // replace updateLocationHref() method in component with an empty function + // to bypass window.location.href that causes test failures + spyOn(comp, 'updateLocationHref').and.callFake(() => {}); + + const EVENT: ButtonEvent = { + button: { + type: ButtonType.EXTURL + } as ButtonConfig, + image: IMAGES[0] as InternalLibImage, + action: Action.NORMAL, + galleryId: GALLERY_ID + }; + comp.onNavigate(EVENT); + }); + + it(`should display modal gallery and call onDownload with downloadable = true`, () => { + const modalGalleryService = fixture.debugElement.injector.get(ModalGalleryService); + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + currentImageConfig: { + downloadable: true + } as CurrentImageConfig + }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + checkElements(fixture); + + const beforeHookSpy: Spy = spyOn(modalGalleryService, 'emitButtonBeforeHook'); + const afterHookSpy: Spy = spyOn(modalGalleryService, 'emitButtonAfterHook'); + + const EVENT: ButtonEvent = { + button: { + type: ButtonType.DOWNLOAD + } as ButtonConfig, + image: IMAGES[0] as InternalLibImage, + action: Action.NORMAL, + galleryId: GALLERY_ID + }; + comp.onDownload(EVENT); + + expect(beforeHookSpy).toHaveBeenCalled(); + expect(afterHookSpy).toHaveBeenCalled(); + }); + + it(`should display modal gallery and call onDownload with downloadable = true and SafeResourceUrl img url as base64`, () => { + const modalGalleryService = fixture.debugElement.injector.get(ModalGalleryService); + const configService = fixture.debugElement.injector.get(ConfigService); + const sanitizer = fixture.debugElement.injector.get(DomSanitizer); + + const base64Image: SafeResourceUrl = sanitizer.bypassSecurityTrustResourceUrl(base64String); + const base64RedImage: SafeResourceUrl = sanitizer.bypassSecurityTrustResourceUrl(base64RedString); + const base64GreenImage: SafeResourceUrl = sanitizer.bypassSecurityTrustResourceUrl(base64GreenString); + + const imagesBase64: InternalLibImage[] = [ + new InternalLibImage(0, { + img: base64Image, + extUrl: 'http://www.google.com' + }), + new InternalLibImage(1, { + img: base64GreenImage, + description: 'Description 2' + }), + new InternalLibImage( + 2, + { + img: base64RedImage, + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + img: base64RedImage, + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ) + ]; + + configService.setConfig(GALLERY_ID, { + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + currentImageConfig: { + downloadable: true + } as CurrentImageConfig + }); + comp.id = GALLERY_ID; + comp.images = imagesBase64; + comp.currentImage = imagesBase64[0]; + fixture.detectChanges(); + + checkElements(fixture); + + const beforeHookSpy: Spy = spyOn(modalGalleryService, 'emitButtonBeforeHook'); + const afterHookSpy: Spy = spyOn(modalGalleryService, 'emitButtonAfterHook'); + + const EVENT: ButtonEvent = { + button: { + type: ButtonType.DOWNLOAD + } as ButtonConfig, + image: imagesBase64[0] as InternalLibImage, + action: Action.NORMAL, + galleryId: GALLERY_ID + }; + comp.onDownload(EVENT); + + expect(beforeHookSpy).toHaveBeenCalled(); + expect(afterHookSpy).toHaveBeenCalled(); + }); + + it(`should display modal gallery and call onDownload with downloadable = true and custom downloadFileName`, () => { + const modalGalleryService = fixture.debugElement.injector.get(ModalGalleryService); + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + currentImageConfig: { + downloadable: true + } as CurrentImageConfig + }); + comp.id = GALLERY_ID; + comp.images = IMAGES_CUSTOM_DOWNLOAD_FILENAME; + comp.currentImage = IMAGES_CUSTOM_DOWNLOAD_FILENAME[0]; + fixture.detectChanges(); + + checkElements(fixture); + + const beforeHookSpy: Spy = spyOn(modalGalleryService, 'emitButtonBeforeHook'); + const afterHookSpy: Spy = spyOn(modalGalleryService, 'emitButtonAfterHook'); + + const EVENT: ButtonEvent = { + button: { + type: ButtonType.DOWNLOAD + } as ButtonConfig, + image: IMAGES_CUSTOM_DOWNLOAD_FILENAME[0] as InternalLibImage, + action: Action.NORMAL, + galleryId: GALLERY_ID + }; + comp.onDownload(EVENT); + + expect(beforeHookSpy).toHaveBeenCalled(); + expect(afterHookSpy).toHaveBeenCalled(); + }); + + it(`should display modal gallery and call onCloseGalleryButton`, () => { + const modalGalleryService = fixture.debugElement.injector.get(ModalGalleryService); + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + checkElements(fixture); + + const beforeHookSpy: Spy = spyOn(modalGalleryService, 'emitButtonBeforeHook'); + + const EVENT: ButtonEvent = { + button: { + type: ButtonType.CLOSE + } as ButtonConfig, + image: IMAGES[0] as InternalLibImage, + action: Action.NORMAL, + galleryId: GALLERY_ID + }; + comp.onCloseGalleryButton(EVENT); + + expect(beforeHookSpy).toHaveBeenCalled(); + }); + + it(`should display modal gallery and call onCloseGallery`, () => { + const modalGalleryService = fixture.debugElement.injector.get(ModalGalleryService); + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + checkElements(fixture); + + const beforeHookSpy: Spy = spyOn(modalGalleryService, 'emitButtonBeforeHook'); + + const EVENT: ImageModalEvent = { + action: Action.NORMAL, + galleryId: GALLERY_ID, + result: true + }; + comp.onCloseGallery(EVENT); + + expect(beforeHookSpy).toHaveBeenCalled(); + }); + + [0, 1, IMAGES.length - 1].forEach(index => { + it(`should display modal gallery and call onChangeCurrentImage with Image at index = ${index}`, () => { + const modalGalleryService = fixture.debugElement.injector.get(ModalGalleryService); + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + const modalGallery: DebugElement = element.query(By.css('div#modal-gallery-wrapper')); + expect(modalGallery).not.toBeNull(); + + const emitShowSpy: Spy = spyOn(modalGalleryService, 'emitShow'); + + const EVENT: ImageModalEvent = { + action: Action.NORMAL, + galleryId: GALLERY_ID, + result: index + }; + comp.onChangeCurrentImage(EVENT); + + expect(emitShowSpy).toHaveBeenCalled(); + }); + }); + + it(`should display modal gallery and call onClickOutside`, () => { + const modalGalleryService = fixture.debugElement.injector.get(ModalGalleryService); + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + const emitCloseSpy: Spy = spyOn(modalGalleryService, 'emitClose'); + const closeSpy: Spy = spyOn(modalGalleryService, 'close'); + + checkElements(fixture); + + comp.onClickOutside(true); + + expect(emitCloseSpy).toHaveBeenCalled(); + expect(closeSpy).toHaveBeenCalled(); + }); + + it(`should display modal gallery and call onImageLoad`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + checkElements(fixture); + + const EVENT: ImageLoadEvent = { + status: true, + index: 0, + id: GALLERY_ID + }; + + comp.onImageLoad(EVENT); + }); + + it(`should display modal gallery and call onClickDot`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + checkElements(fixture); + + comp.onClickDot(1); + }); + + it(`should display modal gallery and call onClickPreview`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + checkElements(fixture); + + const EVENT: ImageModalEvent = { + action: Action.NORMAL, + galleryId: GALLERY_ID, + result: 1 + }; + + comp.onClickPreview(EVENT); + }); + + it(`should display modal gallery and updateImages via modalGalleryService`, () => { + const modalGalleryService: ModalGalleryService = fixture.debugElement.injector.get(ModalGalleryService); + const configService: ConfigService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + checkElements(fixture); + + // change IMAGES array pushing a new Image (equals to the first one) + modalGalleryService.updateModalImages([...IMAGES, IMAGES[0]]); + }); + }); + + describe('---NO---', () => { + + [-1, IMAGES.length + 1].forEach(index => { + it(`should display modal gallery and call onChangeCurrentImage without changing image, because index ${index} is out of bound.`, () => { + const modalGalleryService = fixture.debugElement.injector.get(ModalGalleryService); + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + checkElements(fixture); + + const emitShowSpy: Spy = spyOn(modalGalleryService, 'emitShow'); + + const EVENT: ImageModalEvent = { + action: Action.NORMAL, + galleryId: GALLERY_ID, + result: index + }; + comp.onChangeCurrentImage(EVENT); + + expect(emitShowSpy).not.toHaveBeenCalled(); + }); + }); + + it(`should display modal gallery and call onClickOutside, but enableCloseOutside is false`, () => { + const modalGalleryService = fixture.debugElement.injector.get(ModalGalleryService); + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + comp.enableCloseOutside = false; + fixture.detectChanges(); + + const emitCloseSpy: Spy = spyOn(modalGalleryService, 'emitClose'); + const closeSpy: Spy = spyOn(modalGalleryService, 'close'); + + checkElements(fixture); + + comp.onClickOutside(true); + + expect(emitCloseSpy).not.toHaveBeenCalled(); + expect(closeSpy).not.toHaveBeenCalled(); + }); + + it(`should display modal gallery and call onDownload with downloadable = false`, () => { + const modalGalleryService = fixture.debugElement.injector.get(ModalGalleryService); + const configService = fixture.debugElement.injector.get(ConfigService); + + configService.setConfig(GALLERY_ID, { + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + currentImageConfig: { + downloadable: false + } as CurrentImageConfig + }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.currentImage = IMAGES[0]; + fixture.detectChanges(); + + checkElements(fixture); + + const beforeHookSpy: Spy = spyOn(modalGalleryService, 'emitButtonBeforeHook'); + const afterHookSpy: Spy = spyOn(modalGalleryService, 'emitButtonAfterHook'); + + const EVENT: ButtonEvent = { + button: { + type: ButtonType.DOWNLOAD + } as ButtonConfig, + image: IMAGES[0] as InternalLibImage, + action: Action.NORMAL, + galleryId: GALLERY_ID + }; + comp.onDownload(EVENT); + + expect(beforeHookSpy).toHaveBeenCalled(); + expect(afterHookSpy).toHaveBeenCalled(); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.component.ts b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.component.ts new file mode 100644 index 00000000..edc90843 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.component.ts @@ -0,0 +1,593 @@ +import { + ChangeDetectionStrategy, ChangeDetectorRef, Component, + HostListener, Inject, OnDestroy, OnInit, PLATFORM_ID, SecurityContext, ViewChild, TemplateRef +} from '@angular/core'; +import { isPlatformBrowser } from '@angular/common'; +import { DomSanitizer } from '@angular/platform-browser'; + +import { Subscription } from 'rxjs'; + +import { DIALOG_DATA } from './modal-gallery.tokens'; +import { Image, ImageModalEvent } from '../../model/image.class'; +import { ConfigService } from '../../services/config.service'; +import { DotsConfig } from '../../model/dots-config.interface'; +import { ButtonConfig, ButtonEvent, ButtonsConfig, ButtonType } from '../../model/buttons-config.interface'; +import { InternalLibImage } from '../../model/image-internal.class'; +import { Action } from '../../model/action.enum'; +import { CurrentImageComponent, ImageLoadEvent } from '../current-image/current-image.component'; +import { IdValidatorService } from '../../services/id-validator.service'; +import { KeyboardConfig } from '../../model/keyboard-config.interface'; +import { PreviewConfig } from '../../model/preview-config.interface'; +import { SlideConfig } from '../../model/slide-config.interface'; +import { AccessibilityConfig } from '../../model/accessibility.interface'; +import { PlainGalleryConfig } from '../../model/plain-gallery-config.interface'; +import { KS_DEFAULT_ACCESSIBILITY_CONFIG } from '../accessibility-default'; +import { CurrentImageConfig } from '../../model/current-image-config.interface'; +import { ModalGalleryService } from './modal-gallery.service'; +import { LibConfig } from '../../model/lib-config.interface'; +import { ModalGalleryConfig } from '../../model/modal-gallery-config.interface'; + +@Component({ + selector: 'ks-modal-gallery', + templateUrl: './modal-gallery.component.html', + styleUrls: ['./modal-gallery.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: false +}) +export class ModalGalleryComponent implements OnInit, OnDestroy { + /** + * Reference to the CurrentImageComponent to invoke methods on it. + */ + @ViewChild(CurrentImageComponent, { static: true }) currentImageComponent: CurrentImageComponent | undefined; + + /** + * Unique id (>=0) of the current instance of this library. This is useful when you are using + * the service to call modal gallery without open it manually. + */ + id: number; + /** + * Object of type `ButtonsConfig` to show/hide buttons. + */ + buttonsConfig: ButtonsConfig | undefined; + /** + * Boolean to enable modal-gallery close behaviour when clicking + * on the semi-transparent background. Enabled by default. + */ + enableCloseOutside = true; + /** + * Object of type `DotsConfig` to init DotsComponent's features. + * For instance, it contains a param to show/hide dots. + */ + dotsConfig: DotsConfig | undefined; + /** + * Object of type `PreviewConfig` to init PreviewsComponent's features. + * For instance, it contains a param to show/hide previews. + */ + previewConfig: PreviewConfig | undefined; + /** + * Object of type `SlideConfig` to init side previews and `infinite sliding`. + */ + slideConfig: SlideConfig | undefined; + /** + * Object of type `AccessibilityConfig` to init custom accessibility features. + * For instance, it contains titles, alt texts, aria-labels and so on. + */ + accessibilityConfig: AccessibilityConfig = KS_DEFAULT_ACCESSIBILITY_CONFIG; + /** + * Object of type `KeyboardConfig` to assign custom keys to ESC, RIGHT and LEFT keyboard's actions. + */ + keyboardConfig: KeyboardConfig | undefined; + /** + * Object of type `PlainGalleryConfig` to configure the plain gallery. + */ + plainGalleryConfig: PlainGalleryConfig | undefined; + /** + * Array of `InternalLibImage` representing the model of this library with all images, thumbs and so on. + */ + images: InternalLibImage[]; + + /** + * Optional template reference to use to render previews. + */ + customPreviewsTemplate?: TemplateRef; + + /** + * `Image` that is visible right now. + */ + currentImage: InternalLibImage; + /** + * Boolean to open the modal gallery. False by default. + */ + showGallery = false; + /** + * Object to configure this component. + */ + libConfig: LibConfig | undefined; + + private updateImagesSubscription: Subscription | undefined; + + /** + * HostListener to catch browser's back button and destroy the gallery. + * This prevents weired behaviour about scrolling. + * Added to fix this issue: https://github.com/Ks89/angular-modal-gallery/issues/159 + */ + @HostListener('window:popstate') + onPopState(): void { + this.closeGallery(); + } + + /** + * HostListener to catch ctrl+s/meta+s and download the current image. + * Inspired by https://netbasal.com/add-keyboard-shortcuts-to-your-angular-app-9bf2e89862b3 + */ + @HostListener('document:keydown.code.control.keyS', ['$event']) // windows + @HostListener('document:keydown.code.meta.keyS', ['$event']) // macOS + onSaveListener(event: KeyboardEvent): void { + event.preventDefault(); + this.downloadImage(); + } + + constructor( + @Inject(DIALOG_DATA) private dialogContent: ModalGalleryConfig, + private modalGalleryService: ModalGalleryService, + // tslint:disable-next-line:ban-types + @Inject(PLATFORM_ID) private platformId: Object, + private changeDetectorRef: ChangeDetectorRef, + private idValidatorService: IdValidatorService, + private configService: ConfigService, + private sanitizer: DomSanitizer + ) { + this.id = (this.dialogContent as ModalGalleryConfig).id; + this.images = (this.dialogContent as ModalGalleryConfig).images as InternalLibImage[]; + this.currentImage = (this.dialogContent as ModalGalleryConfig).currentImage as InternalLibImage; + this.libConfig = (this.dialogContent as ModalGalleryConfig).libConfig; + this.customPreviewsTemplate = (this.dialogContent as ModalGalleryConfig).previewsTemplate; + this.configService.setConfig(this.id, this.libConfig); + + this.updateImagesSubscription = this.modalGalleryService.updateImages$.subscribe((images: Image[]) => { + this.images = images.map((image: Image) => { + const newImage: InternalLibImage = Object.assign({}, image, { previouslyLoaded: false }); + return newImage; + }); + this.initImages(); + this.images.forEach((image: InternalLibImage) => { + if (image.id === this.currentImage.id) { + this.currentImage = image; + } + }); + this.changeDetectorRef.markForCheck(); + }); + } + + /** + * Method ´ngOnInit´ to init images calling `initImages()`. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called only one time!!! + */ + ngOnInit(): void { + this.idValidatorService.checkAndAdd(this.id); + + // id is a mandatory input and must a number > 0 + if ((!this.id && this.id !== 0) || this.id < 0) { + throw new Error( + `'[id]="a number >= 0"' is a mandatory input in angular-modal-gallery.` + + `If you are using multiple instances of this library, please be sure to use different ids` + ); + } + + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig || !libConfig.dotsConfig) { + throw new Error('Internal library error - libConfig and dotsConfig must be defined'); + } + + this.dotsConfig = libConfig.dotsConfig; + + setTimeout(() => { + this.initImages(); + }, 0); + } + + /** + * Method called by custom upper buttons. + * @param event ButtonEvent event payload + */ + onCustomEmit(event: ButtonEvent): void { + const eventToEmit: ButtonEvent = this.getButtonEventToEmit(event); + this.modalGalleryService.emitButtonBeforeHook(eventToEmit); + this.modalGalleryService.emitButtonAfterHook(eventToEmit); + } + + /** + * Method called by the full-screen upper button. + * @param event ButtonEvent event payload + */ + onFullScreen(event: ButtonEvent): void { + const eventToEmit: ButtonEvent = this.getButtonEventToEmit(event); + this.modalGalleryService.emitButtonBeforeHook(eventToEmit); + + // tslint:disable-next-line:no-any + const doc: any = document as any; + // tslint:disable-next-line:no-any + const docEl: any = document.documentElement as any; + + const fullscreenDisabled: boolean = !doc.fullscreenElement && !doc.webkitFullscreenElement; + + // In Safari `requestFullscreen` and `exitFullscreen` are undefined. Safari requires the prefixed version `webkit-` + // and it doesn't return promises. + + // I cannot call `emitButtonAfterHook` only if requestFullScreen is successful, because there are no guarantees across browsers and + // I should also handle the case with keyboard "esc" button. + + if (fullscreenDisabled) { + if (docEl.requestFullscreen) { + docEl.requestFullscreen() + .then(() => { + }) + .catch(() => { + console.error('Cannot request full screen'); + }); + } else if (docEl.webkitRequestFullscreen) { + // For Safari and it doesn't return a promise + docEl.webkitRequestFullscreen(); + } + } else { + if (doc.exitFullscreen) { + doc.exitFullscreen() + .then(() => { + }) + .catch(() => { + console.error('Cannot request exit full screen'); + }); + } else if (doc.webkitExitFullscreen) { + // For Safari and it doesn't return a promise + doc.webkitExitFullscreen(); + } + } + + this.modalGalleryService.emitButtonAfterHook(eventToEmit); + } + + /** + * Method called by the delete upper button. + * @param event ButtonEvent event payload + */ + onDelete(event: ButtonEvent): void { + const eventToEmit: ButtonEvent = this.getButtonEventToEmit(event); + this.modalGalleryService.emitButtonBeforeHook(eventToEmit); + + if (this.images.length === 1) { + this.closeGallery(); + } + + if (!this.currentImageComponent) { + throw new Error('currentImageComponent must be defined'); + } + + const imageIndexToDelete: number = this.currentImageComponent.getIndexToDelete(event.image as InternalLibImage); + if (imageIndexToDelete === this.images.length - 1) { + // last image + this.currentImageComponent.prevImage(); + } else { + this.currentImageComponent.nextImage(); + } + + this.modalGalleryService.emitButtonAfterHook(eventToEmit); + } + + /** + * Method called by the navigate upper button. + * @param event ButtonEvent event payload + */ + onNavigate(event: ButtonEvent): void { + const eventToEmit: ButtonEvent = this.getButtonEventToEmit(event); + this.modalGalleryService.emitButtonBeforeHook(eventToEmit); + // To support SSR + if (isPlatformBrowser(this.platformId)) { + if (eventToEmit.image && eventToEmit.image.modal.extUrl) { + // where I should open this link? The current tab or another one? + if (eventToEmit.button && eventToEmit.button.extUrlInNewTab) { + // in this case I should use target _blank to open the url in a new tab, however these is a security issue. + // Prevent Reverse Tabnabbing's attacks (https://www.owasp.org/index.php/Reverse_Tabnabbing) + // Some resources: + // - https://www.owasp.org/index.php/HTML5_Security_Cheat_Sheet#Tabnabbing + // - https://medium.com/@jitbit/target-blank-the-most-underestimated-vulnerability-ever-96e328301f4c + // - https://developer.mozilla.org/en-US/docs/Web/API/Window/open + const newWindow: Window | null = window.open(eventToEmit.image.modal.extUrl, 'noopener,noreferrer,'); + // it returns null if the call failed, so I have to do this check + if (newWindow) { + newWindow.opener = null; // required to prevent security issues + // emit only in case of success + this.modalGalleryService.emitButtonAfterHook(eventToEmit); + } + } else { + this.updateLocationHref(eventToEmit.image.modal.extUrl); + // emit only in case of success + this.modalGalleryService.emitButtonAfterHook(eventToEmit); + } + } + } + } + + /** + * This method is defined to be spied and replaced in unit testing with a fake method call. + * It must be public to be able to use jasmine spyOn method. + * @param newHref string new url + */ + updateLocationHref(newHref: string) { + window.location.href = newHref; + } + + /** + * Method called by the download upper button. + * @param event ButtonEvent event payload + */ + onDownload(event: ButtonEvent): void { + const eventToEmit: ButtonEvent = this.getButtonEventToEmit(event); + this.modalGalleryService.emitButtonBeforeHook(eventToEmit); + this.downloadImage(); + this.modalGalleryService.emitButtonAfterHook(eventToEmit); + } + + /** + * Method called by the close upper button. + * @param event ButtonEvent event payload + * @param action Action that triggered the close method. `Action.NORMAL` by default + */ + onCloseGalleryButton(event: ButtonEvent, action: Action = Action.NORMAL): void { + const eventToEmit: ButtonEvent = this.getButtonEventToEmit(event); + this.modalGalleryService.emitButtonBeforeHook(eventToEmit); + this.closeGallery(action, false); + } + + /** + * Method called by CurrentImageComponent. + * @param event ImageModalEvent event payload + * @param action Action that triggered the close method. `Action.NORMAL` by default + */ + onCloseGallery(event: ImageModalEvent, action: Action = Action.NORMAL): void { + // remap ImageModalEvent to ButtonEvent + const buttonEvent: ButtonEvent = { + button: { + type: ButtonType.CLOSE + } as ButtonConfig, + image: null, + action: event.action, + galleryId: event.galleryId + }; + this.modalGalleryService.emitButtonBeforeHook(buttonEvent); + this.closeGallery(action, false); + } + + /** + * Method to close the modal gallery specifying the action. + * @param action Action action type. `Action.NORMAL` by default + * @param clickOutside boolean that is true if called clicking on the modal background. False by default. + */ + closeGallery(action: Action = Action.NORMAL, clickOutside: boolean = false): void { + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + + this.modalGalleryService.emitClose(new ImageModalEvent(this.id, action, true)); + this.modalGalleryService.close(this.id, clickOutside); + } + + /** + * Method called when the image changes and used to update the `currentImage` object. + * @param event ImageModalEvent event payload + */ + onChangeCurrentImage(event: ImageModalEvent): void { + const newIndex: number = event.result as number; + if (newIndex < 0 || newIndex >= this.images.length) { + return; + } + + this.currentImage = this.images[newIndex]; + + // emit current visible image index + this.modalGalleryService.emitShow(new ImageModalEvent(this.id, event.action, newIndex + 1)); + + // emit first/last event based on newIndex value + this.emitBoundaryEvent(event.action, newIndex); + } + + /** + * Method called when you click 'outside' (i.e. on the semi-transparent background) + * to close the modal gallery if `enableCloseOutside` is true. + * @param event boolean that is true to close the modal gallery, false otherwise + */ + onClickOutside(event: boolean): void { + if (event && this.enableCloseOutside) { + this.closeGallery(Action.CLICK, true); + } + } + + /** + * Method called when an image is loaded and the loading spinner has gone. + * It sets the previouslyLoaded flag inside the Image to hide loading spinner when displayed again. + * @param event ImageLoadEvent event payload + */ + onImageLoad(event: ImageLoadEvent): void { + // sets as previously loaded the image with index specified by `event.status` + this.images = this.images.map((img: InternalLibImage) => { + if (img && img.id === event.id) { + return Object.assign({}, img, { previouslyLoaded: event.status }); + } + return img; + }); + } + + /** + * Method called when a dot is clicked and used to update the current image. + * @param index number index of the clicked dot + */ + onClickDot(index: number): void { + this.currentImage = this.images[index]; + } + + /** + * Method called when an image preview is clicked and used to update the current image. + * @param event ImageModalEvent preview image + */ + onClickPreview(event: ImageModalEvent): void { + this.onChangeCurrentImage(event); + } + + /** + * Method to cleanup resources. + * This is an angular lifecycle hook that is called when this component is destroyed. + */ + ngOnDestroy(): void { + if (this.updateImagesSubscription) { + this.updateImagesSubscription.unsubscribe(); + } + this.idValidatorService.remove(this.id); + } + + /** + * Method to download the current image, only if `downloadable` is true. + * @private + */ + private downloadImage(): void { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + + const currentImageConfig: CurrentImageConfig | undefined = libConfig.currentImageConfig; + if (currentImageConfig && !currentImageConfig.downloadable) { + return; + } + this.downloadImageAllBrowsers(); + } + + /** + * Method to convert a base64 to a Blob + * @param base64Data string with base64 data + * @param contentType string with the MIME type + * @return Blob converted from the input base64Data + * @private + */ + private base64toBlob(base64Data: string, contentType: string = ''): Blob { + const sliceSize = 1024; + const byteCharacters: string = atob(base64Data); + const bytesLength: number = byteCharacters.length; + const slicesCount: number = Math.ceil(bytesLength / sliceSize); + const byteArrays: Array = new Array(slicesCount); + for (let sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) { + const begin: number = sliceIndex * sliceSize; + const end: number = Math.min(begin + sliceSize, bytesLength); + const bytes: Array = new Array(end - begin); + for (let offset = begin, i = 0; offset < end; ++i, ++offset) { + bytes[i] = byteCharacters[offset].charCodeAt(0); + } + byteArrays[sliceIndex] = new Uint8Array(bytes); + } + return new Blob(byteArrays, { type: contentType }); + } + + /** + * Private method to download the current image for all browsers. + * @private + */ + private downloadImageAllBrowsers(): void { + const link = document.createElement('a'); + let isBase64 = false; + let img: string; + // convert a SafeResourceUrl to a string + if (typeof this.currentImage.modal.img === 'string') { + img = this.currentImage.modal.img as string; + } else { + // if it's a SafeResourceUrl + img = this.sanitizer.sanitize(SecurityContext.RESOURCE_URL, this.currentImage.modal.img) as string; + } + if (img.includes('data:image/') || img.includes(';base64,')) { + const extension: string = img.replace('data:image/', '').split(';base64,')[0]; + const pureBase64: string = img.split(';base64,')[1]; + const blob: Blob = this.base64toBlob(pureBase64, 'image/' + extension); + link.href = URL.createObjectURL(blob); + isBase64 = true; + link.setAttribute('download', this.getFileName(this.currentImage, isBase64, extension)); + } else { + link.href = img; + link.setAttribute('download', this.getFileName(this.currentImage, isBase64)); + } + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } + + /** + * Private method to get the `ButtonEvent` to emit, merging the input `ButtonEvent` + * with the current image. + * @param event ButtonEvent event payload to return + * @returns ButtonEvent event payload with the current image included + * @private + */ + private getButtonEventToEmit(event: ButtonEvent): ButtonEvent { + return Object.assign(event, { image: this.currentImage }); + } + + /** + * Private method to get the file name from an input path. + * This is used either to get the image's name from its path or from the Image itself, + * if specified as 'downloadFileName' by the user. + * @param image Image image to extract its file name + * @param isBase64 boolean to set if the image is a base64 file or not. False by default. + * @param base64Extension string to force the extension of the base64 image. Empty string by default. + * @returns string string file name of the input image. + * @private + */ + private getFileName(image: Image, isBase64: boolean = false, base64Extension: string = ''): string { + if (!image.modal.downloadFileName || image.modal.downloadFileName.length === 0) { + if (isBase64) { + return `Image-${image.id}.${base64Extension !== '' ? base64Extension : 'png'}`; + } else { + return (image.modal.img as string).replace(/^.*[\\\/]/, ''); + } + } else { + return image.modal.downloadFileName; + } + } + + /** + * Private method to initialize `images` as array of `Image`s. + * Also, it will emit ImageModalEvent to say that images are loaded. + * @private + */ + private initImages(): void { + this.modalGalleryService.emitHasData(new ImageModalEvent(this.id, Action.LOAD, true)); + + const currentIndex: number = this.images.indexOf(this.currentImage); + // emit a new ImageModalEvent with the index of the current image + this.modalGalleryService.emitShow(new ImageModalEvent(this.id, Action.LOAD, currentIndex + 1)); + + // emit first/last event based on newIndex value + this.emitBoundaryEvent(Action.NORMAL, currentIndex); + + this.showGallery = this.images.length > 0; + } + + /** + * Private method to emit events when either the last or the first image are visible. + * @param action Action Enum of type Action that represents the source of the event that changed the + * current image to the first one or the last one. + * @param indexToCheck number is the index number of the image (the first or the last one). + * @private + */ + private emitBoundaryEvent(action: Action, indexToCheck: number): void { + // to emit first/last event + switch (indexToCheck) { + case 0: + this.modalGalleryService.emitFirstImage(new ImageModalEvent(this.id, action, true)); + break; + case this.images.length - 1: + this.modalGalleryService.emitLastImage(new ImageModalEvent(this.id, action, true)); + break; + } + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.service.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.service.spec.ts new file mode 100644 index 00000000..56af5e00 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.service.spec.ts @@ -0,0 +1,511 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { inject, TestBed, waitForAsync } from '@angular/core/testing'; +import { Overlay, OverlayModule } from '@angular/cdk/overlay'; + +import { ModalGalleryService } from './modal-gallery.service'; +import { ConfigService } from '../../services/config.service'; +import { Image, ImageModalEvent } from '../../model/image.class'; +import { ModalGalleryRef } from './modal-gallery-ref'; +import { Action } from '../../model/action.enum'; +import { ButtonConfig, ButtonEvent, ButtonType } from '../../model/buttons-config.interface'; +import { InternalLibImage } from '../../model/image-internal.class'; +import { ModalGalleryComponent } from './modal-gallery.component'; +import { UpperButtonsComponent } from '../upper-buttons/upper-buttons.component'; +import { CurrentImageComponent } from '../current-image/current-image.component'; +import { DotsComponent } from '../dots/dots.component'; +import { PreviewsComponent } from '../previews/previews.component'; +import { LoadingSpinnerComponent } from '../current-image/loading-spinner/loading-spinner.component'; +import { FallbackImageDirective } from '../../directives/fallback-image.directive'; +import { ClickOutsideDirective } from '../../directives/click-outside.directive'; +import { DescriptionDirective } from '../../directives/description.directive'; +import { KeyboardNavigationDirective } from '../../directives/keyboard-navigation.directive'; +import { SizeDirective } from '../../directives/size.directive'; +import { WrapDirective } from '../../directives/wrap.directive'; +import { DirectionDirective } from '../../directives/direction.directive'; +import { ATagBgImageDirective } from '../../directives/a-tag-bg-image.directive'; + +const IMAGES: Image[] = [ + new Image(0, { + // modal + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new Image(1, { + // modal + img: '../assets/images/gallery/img2.png', + description: 'Description 2' + }), + new Image( + 2, + { + // modal + img: '../assets/images/gallery/img3.jpg', + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + // plain + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new Image(3, { + // modal + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new Image( + 4, + { + // modal + img: '../assets/images/gallery/img5.jpg' + }, + { + // plain + img: '../assets/images/gallery/thumbs/img5.jpg' + } + ) +]; + +describe('ModalGalleryService', () => { + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [OverlayModule], + declarations: [ModalGalleryComponent, + UpperButtonsComponent, CurrentImageComponent, DotsComponent, PreviewsComponent, LoadingSpinnerComponent, + FallbackImageDirective, ClickOutsideDirective, DescriptionDirective, KeyboardNavigationDirective, + SizeDirective, WrapDirective, DirectionDirective, ATagBgImageDirective] + }).overrideComponent(ModalGalleryComponent, { + set: { + providers: [ + { + provide: ModalGalleryService, + useClass: ModalGalleryService + }, + { + provide: ConfigService, + useClass: ConfigService + }, + { + provide: Overlay, + useClass: Overlay + } + ] + } + }); + }) + ); + + it('should instantiate service when inject service', + inject([ModalGalleryService], (service: ModalGalleryService) => { + expect(service instanceof ModalGalleryService).toEqual(true); + }) + ); + + describe('#open()', () => { + describe('---YES---', () => { + it(`should call open and return a ModalGalleryRef instance`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ref: ModalGalleryRef | undefined = service.open({ + id: 1, + images: IMAGES, + currentImage: IMAGES[0] + }); + expect(ref).toBeDefined(); + expect(ref instanceof ModalGalleryRef).toBeTrue(); + }) + ); + + it('should trigger attachment of the component to the overlay', inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const config = { + id: ID, + images: IMAGES, + currentImage: IMAGES[0] + }; + let hasEmitted = false; + + service.triggerAttachToOverlay.subscribe(payload => { + expect(payload.config).toEqual(config); + hasEmitted = true; + }); + + service.open(config); + + expect(hasEmitted).toBeTrue(); + })); + }); + }); + + describe('#updateModalImages()', () => { + it(`should call updateModalImages`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + service.updateImages$.subscribe((images: Image[]) => { + expect(images).toEqual(IMAGES); + }); + service.updateModalImages(IMAGES); + }) + ); + }); + + describe('#emitClose()', () => { + describe('---YES---', () => { + it(`should call close with clickOutside=false`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const ref: ModalGalleryRef | undefined = service.open({ + id: ID, + images: IMAGES, + currentImage: IMAGES[0] + }); + expect(ref).toBeDefined(); + expect(ref instanceof ModalGalleryRef).toBeTrue(); + // the close + service.close(ID, false); + }) + ); + + it(`should call close with clickOutside=true`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const ref: ModalGalleryRef | undefined = service.open({ + id: ID, + images: IMAGES, + currentImage: IMAGES[0] + }); + expect(ref).toBeDefined(); + expect(ref instanceof ModalGalleryRef).toBeTrue(); + // the close + service.close(ID, true); + }) + ); + }); + + describe('---NO---', () => { + it(`should call close without calling open before with clickOutside=false`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + // the close + service.close(ID, false); + }) + ); + + // aggiungere caso clickOutside e libConfig.enableCloseOutside + + it(`should call close without calling open before with clickOutside=true`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + // the close + service.close(ID, true); + }) + ); + }); + }); + + describe('#emitClose()', () => { + describe('---YES---', () => { + it(`should call emitClose`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const EVENT: ImageModalEvent = new ImageModalEvent(ID, Action.NORMAL, true); + + const ref: ModalGalleryRef | undefined = service.open({ + id: ID, + images: IMAGES, + currentImage: IMAGES[0] + }); + expect(ref).toBeDefined(); + expect(ref instanceof ModalGalleryRef).toBeTrue(); + + (ref as ModalGalleryRef).close$.subscribe((event: ImageModalEvent) => { + expect(EVENT).toEqual(event); + }); + + service.emitClose(EVENT); + }) + ); + }); + + describe('---NO---', () => { + it(`shouldn't call emitClose because gallery is closed`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const EVENT: ImageModalEvent = new ImageModalEvent(ID, Action.NORMAL, true); + // don't trigger event + service.emitClose(EVENT); + }) + ); + }); + }); + + describe('#emitShow()', () => { + describe('---YES---', () => { + it(`should call emitShow`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const EVENT: ImageModalEvent = new ImageModalEvent(ID, Action.NORMAL, true); + + const ref: ModalGalleryRef | undefined = service.open({ + id: ID, + images: IMAGES, + currentImage: IMAGES[0] + }); + expect(ref).toBeDefined(); + expect(ref instanceof ModalGalleryRef).toBeTrue(); + + (ref as ModalGalleryRef).show$.subscribe((event: ImageModalEvent) => { + expect(EVENT).toEqual(event); + }); + + service.emitShow(EVENT); + }) + ); + }); + + describe('---NO---', () => { + it(`shouldn't call emitShow because gallery is closed`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const EVENT: ImageModalEvent = new ImageModalEvent(ID, Action.NORMAL, true); + // don't trigger event + service.emitShow(EVENT); + }) + ); + }); + }); + + describe('#emitFirstImage()', () => { + describe('---YES---', () => { + it(`should call emitFirstImage`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const EVENT: ImageModalEvent = new ImageModalEvent(ID, Action.NORMAL, true); + + const ref: ModalGalleryRef | undefined = service.open({ + id: ID, + images: IMAGES, + currentImage: IMAGES[0] + }); + expect(ref).toBeDefined(); + expect(ref instanceof ModalGalleryRef).toBeTrue(); + + (ref as ModalGalleryRef).firstImage$.subscribe((event: ImageModalEvent) => { + expect(EVENT).toEqual(event); + }); + + service.emitFirstImage(EVENT); + }) + ); + }); + + describe('---NO---', () => { + it(`shouldn't call emitFirstImage because gallery is closed`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const EVENT: ImageModalEvent = new ImageModalEvent(ID, Action.NORMAL, true); + // don't trigger event + service.emitFirstImage(EVENT); + }) + ); + }); + }); + + describe('#emitLastImage()', () => { + describe('---YES---', () => { + it(`should call emitLastImage`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const EVENT: ImageModalEvent = new ImageModalEvent(ID, Action.NORMAL, true); + + const ref: ModalGalleryRef | undefined = service.open({ + id: ID, + images: IMAGES, + currentImage: IMAGES[0] + }); + expect(ref).toBeDefined(); + expect(ref instanceof ModalGalleryRef).toBeTrue(); + + (ref as ModalGalleryRef).lastImage$.subscribe((event: ImageModalEvent) => { + expect(EVENT).toEqual(event); + }); + + service.emitLastImage(EVENT); + }) + ); + }); + + describe('---NO---', () => { + it(`shouldn't call emitLastImage because gallery is closed`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const EVENT: ImageModalEvent = new ImageModalEvent(ID, Action.NORMAL, true); + // don't trigger event + service.emitLastImage(EVENT); + }) + ); + }); + }); + + describe('#emitHasData()', () => { + describe('---YES---', () => { + it(`should call emitHasData`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const EVENT: ImageModalEvent = new ImageModalEvent(ID, Action.NORMAL, true); + + const ref: ModalGalleryRef | undefined = service.open({ + id: ID, + images: IMAGES, + currentImage: IMAGES[0] + }); + expect(ref).toBeDefined(); + expect(ref instanceof ModalGalleryRef).toBeTrue(); + + (ref as ModalGalleryRef).hasData$.subscribe((event: ImageModalEvent) => { + expect(EVENT).toEqual(event); + }); + + service.emitHasData(EVENT); + }) + ); + }); + + describe('---NO---', () => { + it(`shouldn't call emitHasData because gallery is closed`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const EVENT: ImageModalEvent = new ImageModalEvent(ID, Action.NORMAL, true); + // don't trigger event + service.emitHasData(EVENT); + }) + ); + }); + }); + + describe('#emitButtonBeforeHook()', () => { + describe('---YES---', () => { + it(`should call emitButtonBeforeHook`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const EVENT: ButtonEvent = { + button: { + type: ButtonType.CLOSE + } as ButtonConfig, + image: IMAGES[ID] as InternalLibImage, + action: Action.NORMAL, + galleryId: ID + }; + + const ref: ModalGalleryRef | undefined = service.open({ + id: ID, + images: IMAGES, + currentImage: IMAGES[0] + }); + expect(ref).toBeDefined(); + expect(ref instanceof ModalGalleryRef).toBeTrue(); + + (ref as ModalGalleryRef).buttonBeforeHook$.subscribe((event: ButtonEvent) => { + expect(EVENT).toEqual(event); + }); + + service.emitButtonBeforeHook(EVENT); + }) + ); + }); + + describe('---NO---', () => { + it(`shouldn't call emitButtonBeforeHook because gallery is closed`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const EVENT: ButtonEvent = { + button: { + type: ButtonType.CLOSE + } as ButtonConfig, + image: IMAGES[ID] as InternalLibImage, + action: Action.NORMAL, + galleryId: ID + }; + // don't trigger event + service.emitButtonBeforeHook(EVENT); + }) + ); + }); + }); + + describe('#emitButtonAfterHook()', () => { + describe('---YES---', () => { + it(`should call emitButtonAfterHook`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const EVENT: ButtonEvent = { + button: { + type: ButtonType.CLOSE + } as ButtonConfig, + image: IMAGES[ID] as InternalLibImage, + action: Action.NORMAL, + galleryId: ID + }; + + const ref: ModalGalleryRef | undefined = service.open({ + id: ID, + images: IMAGES, + currentImage: IMAGES[0] + }); + expect(ref).toBeDefined(); + expect(ref instanceof ModalGalleryRef).toBeTrue(); + + (ref as ModalGalleryRef).buttonAfterHook$.subscribe((event: ButtonEvent) => { + expect(EVENT).toEqual(event); + }); + + service.emitButtonAfterHook(EVENT); + }) + ); + }); + + describe('---NO---', () => { + it(`shouldn't call emitButtonAfterHook because gallery is closed`, + inject([ModalGalleryService], (service: ModalGalleryService) => { + const ID: number = 1; + const EVENT: ButtonEvent = { + button: { + type: ButtonType.CLOSE + } as ButtonConfig, + image: IMAGES[ID] as InternalLibImage, + action: Action.NORMAL, + galleryId: ID + }; + // don't trigger event + service.emitButtonAfterHook(EVENT); + }) + ); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.service.ts b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.service.ts new file mode 100644 index 00000000..819217d2 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.service.ts @@ -0,0 +1,207 @@ +import { EventEmitter, Injectable } from '@angular/core'; +import { GlobalPositionStrategy, Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay'; +import { Subject } from 'rxjs'; + +import { ModalGalleryRef } from './modal-gallery-ref'; +import { Image, ImageModalEvent } from '../../model/image.class'; +import { ConfigService } from '../../services/config.service'; +import { ButtonEvent } from '../../model/buttons-config.interface'; +import { ModalGalleryConfig } from '../../model/modal-gallery-config.interface'; +import { LibConfig } from '../../model/lib-config.interface'; + +// private interface used only in this file +interface ModalDialogConfig { + panelClass: string; + hasBackdrop: boolean; + backdropClass: string; +} + +/** + * Payload to be emitted via {@link triggerAttachToOverlay} to enable {@link AttachToOverlayService} + * to attach the {@link ModalGalleryComponent} to the overlay + */ +export interface AttachToOverlayPayload { + /** + * Overlay object created using Angular CDK APIs + */ + overlayRef: OverlayRef; + /** + * Dialog data to be injected into the {@link ModalGalleryComponent} + * contains: id, array of images, current image and optionally the configuration object + */ + config: ModalGalleryConfig; + /** + * Object to control the dialog instance + */ + dialogRef: ModalGalleryRef; +} + +const DEFAULT_DIALOG_CONFIG: ModalDialogConfig = { + hasBackdrop: true, + backdropClass: 'ks-modal-gallery-backdrop', + panelClass: 'ks-modal-gallery-panel' +}; + +@Injectable({providedIn: 'root'}) +export class ModalGalleryService { + private updateImages = new Subject(); + updateImages$ = this.updateImages.asObservable(); + + private dialogRef: ModalGalleryRef | undefined; + + public triggerAttachToOverlay = new EventEmitter(); + + constructor(private overlay: Overlay, private configService: ConfigService) { + } + + /** + * Method to open modal gallery passing the configuration + * @param config ModalGalleryConfig that contains: id, array of images, current image and optionally the configuration object + * @return ModalGalleryRef | undefined is the object used to listen for events. + */ + open(config: ModalGalleryConfig): ModalGalleryRef | undefined { + // Returns an OverlayRef which is a PortalHost + const overlayRef: OverlayRef = this.createOverlay(); + // Instantiate a reference to the dialog + this.dialogRef = new ModalGalleryRef(overlayRef); + // Attach dialog container + this.triggerAttachToOverlay.emit({ + overlayRef, + config, + dialogRef: this.dialogRef + }); + overlayRef.backdropClick().subscribe(() => { + if (this.dialogRef) { + this.dialogRef.closeModal(); + } + }); + return this.dialogRef; + } + + /** + * Method to close a modal gallery previously opened. + * @param id Unique identifier of the modal gallery + * @param clickOutside boolean is true if closed clicking on the modal backdrop, false otherwise. + */ + close(id: number, clickOutside: boolean): void { + const libConfig: LibConfig | undefined = this.configService.getConfig(id); + if (clickOutside) { + if (this.dialogRef && libConfig && libConfig.enableCloseOutside) { + this.dialogRef.closeModal(); + } + } else { + if (this.dialogRef) { + this.dialogRef.closeModal(); + } + } + } + + /** + * Method to update images array. + * @param images Image[] updated array of images + */ + updateModalImages(images: Image[]): void { + this.updateImages.next(images); + } + + /** + * Method to emit close event. + * @param event ImageModalEvent is the event payload + */ + emitClose(event: ImageModalEvent): void { + if (!this.dialogRef) { + return; + } + this.dialogRef.emitClose(event); + } + + /** + * Method to emit show event. + * @param event ImageModalEvent is the event payload + */ + emitShow(event: ImageModalEvent): void { + if (!this.dialogRef) { + return; + } + this.dialogRef.emitShow(event); + } + + /** + * Method to emit firstImage event. + * @param event ImageModalEvent is the event payload + */ + emitFirstImage(event: ImageModalEvent): void { + if (!this.dialogRef) { + return; + } + this.dialogRef.emitFirstImage(event); + } + + /** + * Method to emit lastImage event. + * @param event ImageModalEvent is the event payload + */ + emitLastImage(event: ImageModalEvent): void { + if (!this.dialogRef) { + return; + } + this.dialogRef.emitLastImage(event); + } + + /** + * Method to emit hasData event. + * @param event ImageModalEvent is the event payload + */ + emitHasData(event: ImageModalEvent): void { + if (!this.dialogRef) { + return; + } + this.dialogRef.emitHasData(event); + } + + /** + * Method to emit buttonBeforeHook event. + * @param event ButtonEvent is the event payload + */ + emitButtonBeforeHook(event: ButtonEvent): void { + if (!this.dialogRef) { + return; + } + this.dialogRef.emitButtonBeforeHook(event); + } + + /** + * Method to emit buttonAfterHook event. + * @param event ButtonEvent is the event payload + */ + emitButtonAfterHook(event: ButtonEvent): void { + if (!this.dialogRef) { + return; + } + this.dialogRef.emitButtonAfterHook(event); + } + + /** + * Private method to create an Overlay using Angular CDK APIs + * @private + */ + private createOverlay(): OverlayRef { + const overlayConfig = this.getOverlayConfig(); + return this.overlay.create(overlayConfig); + } + + /** + * Private method to create an OverlayConfig instance + * @private + */ + private getOverlayConfig(): OverlayConfig { + const positionStrategy: GlobalPositionStrategy = this.overlay.position().global().centerHorizontally().centerVertically(); + return new OverlayConfig({ + hasBackdrop: DEFAULT_DIALOG_CONFIG.hasBackdrop, + backdropClass: DEFAULT_DIALOG_CONFIG.backdropClass, + panelClass: DEFAULT_DIALOG_CONFIG.panelClass, + scrollStrategy: this.overlay.scrollStrategies.block(), + positionStrategy + }); + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.tokens.ts b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.tokens.ts new file mode 100644 index 00000000..86a272de --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/modal-gallery/modal-gallery.tokens.ts @@ -0,0 +1,28 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { InjectionToken } from '@angular/core'; +import { ModalGalleryConfig } from '../../model/modal-gallery-config.interface'; + +export const DIALOG_DATA = new InjectionToken('DIALOG_DATA'); diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/plain-gallery/plain-gallery.component.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/components/plain-gallery/plain-gallery.component.spec.ts new file mode 100644 index 00000000..2a01c163 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/plain-gallery/plain-gallery.component.spec.ts @@ -0,0 +1,523 @@ +/* + * Copyright (C) 2017-2024 Stefano Cappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// -------------------------------------------------- +// -------------------------------------------------- +// TODO add custom layout unit testing +// -------------------------------------------------- +// -------------------------------------------------- + +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { DebugElement } from '@angular/core'; +import { By } from '@angular/platform-browser'; + +import { AccessibilityConfig } from '../../model/accessibility.interface'; +import { KS_DEFAULT_ACCESSIBILITY_CONFIG } from '../../components/accessibility-default'; +import { InternalLibImage } from '../../model/image-internal.class'; +import { PlainGalleryComponent } from './plain-gallery.component'; +import { Size } from '../../model/size.interface'; +import { SizeDirective } from '../../directives/size.directive'; +import { WrapDirective } from '../../directives/wrap.directive'; +import { DirectionDirective } from '../../directives/direction.directive'; +import { ATagBgImageDirective } from '../../directives/a-tag-bg-image.directive'; +import { GridLayout, LineLayout, PlainGalleryStrategy } from '../../model/plain-gallery-config.interface'; +import { ConfigService } from '../../services/config.service'; +import { FallbackImageDirective } from '../../directives/fallback-image.directive'; + +let comp: PlainGalleryComponent; +let fixture: ComponentFixture; + +const CUSTOM_ACCESSIBILITY: AccessibilityConfig = Object.assign({}, KS_DEFAULT_ACCESSIBILITY_CONFIG); +CUSTOM_ACCESSIBILITY.plainGalleryContentAriaLabel = 'custom plainGalleryContentAriaLabel'; +CUSTOM_ACCESSIBILITY.plainGalleryContentTitle = 'custom plainGalleryContentTitle'; + +const DEFAULT_PLAIN_SIZE: Size = {width: 'auto', height: '50px'}; +const CUSTOM_SIZE: Size = {height: '40px', width: '40px'}; +const CUSTOM_SIZE_AUTO_HEIGHT: Size = {height: 'auto', width: '40px'}; +const CUSTOM_SIZE_AUTO_WIDTH: Size = {height: '40px', width: 'auto'}; +const CUSTOM_SIZES: Size[] = [CUSTOM_SIZE, CUSTOM_SIZE_AUTO_HEIGHT, CUSTOM_SIZE_AUTO_WIDTH]; + +const GALLERY_ID = 1; + +const IMAGES: InternalLibImage[] = [ + new InternalLibImage(0, { + // modal + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new InternalLibImage(1, { + // modal + img: '../assets/images/gallery/img2.png', + description: 'Description 2' + }), + new InternalLibImage( + 2, + { + // modal + img: '../assets/images/gallery/img3.jpg', + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + // plain + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new InternalLibImage(3, { + // modal + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new InternalLibImage( + 4, + { + // modal + img: '../assets/images/gallery/img5.jpg' + }, + { + // plain + img: '../assets/images/gallery/thumbs/img5.jpg' + } + ) +]; + +function initTestBed(): void { + TestBed.configureTestingModule({ + declarations: [PlainGalleryComponent, SizeDirective, WrapDirective, DirectionDirective, ATagBgImageDirective, FallbackImageDirective] + }).overrideComponent(PlainGalleryComponent, { + set: { + providers: [ + { + provide: ConfigService, + useClass: ConfigService + } + ] + } + }); +} + +describe('PlainGalleryComponent', () => { + beforeEach(() => { + initTestBed(); + fixture = TestBed.createComponent(PlainGalleryComponent); + comp = fixture.componentInstance; + }); + + it('should instantiate it', () => expect(comp).not.toBeNull()); + + describe('---YES---', () => { + + it(`should display plain gallery with img tags and click on a thumb`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, {accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG}); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const plainGallery: DebugElement = element.query(By.css('div.plain-container')); + expect(plainGallery.name).toBe('div'); + expect(plainGallery.attributes.ksDirection).toBe(''); + expect(plainGallery.attributes.ksWrap).toBe(''); + expect(plainGallery.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.plainGalleryContentTitle); + expect(plainGallery.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.plainGalleryContentAriaLabel); + expect(plainGallery.styles['flex-direction']).toBe('row'); + expect(plainGallery.styles['justify-content']).toBe('flex-start'); + + const plainImages: DebugElement[] = plainGallery.children; + expect(plainImages.length).toBe(IMAGES.length); + expect(plainImages[0].name).toBe('img'); + expect(plainImages[0].attributes.role).toBe('img'); + expect(plainImages[0].properties.src).toBe(IMAGES[0].modal.img); + expect(plainImages[0].attributes.class).toBe('image'); + expect(plainImages[0].attributes['aria-label']).toBeUndefined(); + expect(plainImages[0].properties.title).toBe('Image 1/5'); + expect(plainImages[0].properties.alt).toBe('Image 1'); + expect(plainImages[0].properties.tabIndex).toBe(0); + expect(plainImages[0].styles.width).toBe(DEFAULT_PLAIN_SIZE.width); + expect(plainImages[0].styles.height).toBe(DEFAULT_PLAIN_SIZE.height); + + expect(plainImages[1].name).toBe('img'); + expect(plainImages[1].attributes.role).toBe('img'); + expect(plainImages[1].properties.src).toBe(IMAGES[1].modal.img); + expect(plainImages[1].attributes.class).toBe('image'); + expect(plainImages[1].attributes['aria-label']).toBeUndefined(); + expect(plainImages[1].properties.title).toBe('Image 2/5 - Description 2'); + expect(plainImages[1].properties.alt).toBe('Image 2'); + expect(plainImages[1].properties.tabIndex).toBe(0); + expect(plainImages[1].styles.width).toBe(DEFAULT_PLAIN_SIZE.width); + expect(plainImages[1].styles.height).toBe(DEFAULT_PLAIN_SIZE.height); + + expect(plainImages[2].name).toBe('img'); + expect(plainImages[2].attributes.role).toBe('img'); + expect(plainImages[2].properties.src).toBe(IMAGES[2].plain?.img); + expect(plainImages[2].attributes.class).toBe('image'); + expect(plainImages[2].attributes['aria-label']).toBe('arial label 2'); + expect(plainImages[2].properties.title).toBe(IMAGES[2].plain?.title); + expect(plainImages[2].properties.alt).toBe(IMAGES[2].plain?.alt); + expect(plainImages[2].properties.tabIndex).toBe(0); + expect(plainImages[2].styles.width).toBe(DEFAULT_PLAIN_SIZE.width); + expect(plainImages[2].styles.height).toBe(DEFAULT_PLAIN_SIZE.height); + + expect(plainImages[3].name).toBe('img'); + expect(plainImages[3].attributes.role).toBe('img'); + expect(plainImages[3].properties.src).toBe(IMAGES[3].modal.img); + expect(plainImages[3].attributes.class).toBe('image'); + expect(plainImages[3].attributes['aria-label']).toBeUndefined(); + expect(plainImages[3].properties.title).toBe('Image 4/5 - Description 4'); + expect(plainImages[3].properties.alt).toBe('Image 4'); + expect(plainImages[3].properties.tabIndex).toBe(0); + expect(plainImages[3].styles.width).toBe(DEFAULT_PLAIN_SIZE.width); + expect(plainImages[3].styles.height).toBe(DEFAULT_PLAIN_SIZE.height); + + expect(plainImages[4].name).toBe('img'); + expect(plainImages[4].attributes.role).toBe('img'); + expect(plainImages[4].properties.src).toBe(IMAGES[4].plain?.img); + expect(plainImages[4].attributes.class).toBe('image'); + expect(plainImages[4].attributes['aria-label']).toBeUndefined(); + expect(plainImages[4].properties.title).toBe('Image 5/5'); + expect(plainImages[4].properties.alt).toBe('Image 5'); + expect(plainImages[4].properties.tabIndex).toBe(0); + expect(plainImages[4].styles.width).toBe(DEFAULT_PLAIN_SIZE.width); + expect(plainImages[4].styles.height).toBe(DEFAULT_PLAIN_SIZE.height); + + comp.clickImage.subscribe((res: number) => { + expect(res).toBe(0); + }); + + plainImages[0].nativeElement.click(); + }); + + it(`should display plain gallery with img tags and custom accessibility config`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, {accessibilityConfig: CUSTOM_ACCESSIBILITY}); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const plainGallery: DebugElement = element.query(By.css('div.plain-container')); + expect(plainGallery.name).toBe('div'); + expect(plainGallery.properties.title).toBe(CUSTOM_ACCESSIBILITY.plainGalleryContentTitle); + expect(plainGallery.attributes['aria-label']).toBe(CUSTOM_ACCESSIBILITY.plainGalleryContentAriaLabel); + expect(plainGallery.styles['flex-direction']).toBe('row'); + expect(plainGallery.styles['justify-content']).toBe('flex-start'); + }); + + CUSTOM_SIZES.forEach((size: Size, index: number) => { + it(`should display plain gallery with img tags and custom sizes. Test i=${index}`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + plainGalleryConfig: { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout( + {width: size.width, height: size.height}, + {length: IMAGES.length, wrap: false}, + 'flex-start' + ) + } + }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const plainGallery: DebugElement = element.query(By.css('div.plain-container')); + const plainImages: DebugElement[] = plainGallery.children; + expect(plainImages.length).toBe(IMAGES.length); + expect(plainImages[0].styles.width).toBe(size.width); + expect(plainImages[0].styles.height).toBe(size.height); + expect(plainImages[1].styles.width).toBe(size.width); + expect(plainImages[1].styles.height).toBe(size.height); + expect(plainImages[2].styles.width).toBe(size.width); + expect(plainImages[2].styles.height).toBe(size.height); + expect(plainImages[3].styles.width).toBe(size.width); + expect(plainImages[3].styles.height).toBe(size.height); + expect(plainImages[4].styles.width).toBe(size.width); + expect(plainImages[4].styles.height).toBe(size.height); + }); + }); + + it(`should display plain gallery row layout with only 2 img tags`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + plainGalleryConfig: { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout( + {width: DEFAULT_PLAIN_SIZE.width, height: DEFAULT_PLAIN_SIZE.height}, + {length: 2, wrap: false}, + 'flex-start' + ) + } + }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const plainGallery: DebugElement = element.query(By.css('div.plain-container')); + const plainImages: DebugElement[] = plainGallery.children; + expect(plainImages.length).toBe(2); + }); + + it(`should display plain gallery row layout with img tags and justify space-around`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + plainGalleryConfig: { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout( + {width: DEFAULT_PLAIN_SIZE.width, height: DEFAULT_PLAIN_SIZE.height}, + {length: IMAGES.length, wrap: false}, + 'space-around' + ) + } + }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const plainGallery: DebugElement = element.query(By.css('div.plain-container')); + expect(plainGallery.styles['flex-direction']).toBe('row'); + expect(plainGallery.styles['justify-content']).toBe('space-around'); + }); + + it(`should display plain gallery column layout with only 2 img tags`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + plainGalleryConfig: { + strategy: PlainGalleryStrategy.COLUMN, + layout: new LineLayout( + {width: DEFAULT_PLAIN_SIZE.width, height: DEFAULT_PLAIN_SIZE.height}, + {length: 2, wrap: false}, + 'flex-start' + ) + } + }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const plainGallery: DebugElement = element.query(By.css('div.plain-container')); + expect(plainGallery.name).toBe('div'); + expect(plainGallery.attributes.ksDirection).toBe(''); + expect(plainGallery.attributes.ksWrap).toBe(''); + expect(plainGallery.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.plainGalleryContentTitle); + expect(plainGallery.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.plainGalleryContentAriaLabel); + expect(plainGallery.styles['flex-direction']).toBe('column'); + expect(plainGallery.styles['justify-content']).toBe('flex-start'); + + const plainImages: DebugElement[] = plainGallery.children; + expect(plainImages.length).toBe(2); + expect(plainImages[0].name).toBe('img'); + expect(plainImages[0].attributes.role).toBe('img'); + expect(plainImages[0].properties.src).toBe(IMAGES[0].modal.img); + expect(plainImages[0].attributes.class).toBe('image'); + expect(plainImages[0].attributes['aria-label']).toBeUndefined(); + expect(plainImages[0].properties.title).toBe('Image 1/5'); + expect(plainImages[0].properties.alt).toBe('Image 1'); + expect(plainImages[0].properties.tabIndex).toBe(0); + expect(plainImages[0].styles.width).toBe(DEFAULT_PLAIN_SIZE.width); + expect(plainImages[0].styles.height).toBe(DEFAULT_PLAIN_SIZE.height); + + expect(plainImages[1].name).toBe('img'); + expect(plainImages[1].attributes.role).toBe('img'); + expect(plainImages[1].properties.src).toBe(IMAGES[1].modal.img); + expect(plainImages[1].attributes.class).toBe('image'); + expect(plainImages[1].attributes['aria-label']).toBeUndefined(); + expect(plainImages[1].properties.title).toBe('Image 2/5 - Description 2'); + expect(plainImages[1].properties.alt).toBe('Image 2'); + expect(plainImages[1].properties.tabIndex).toBe(0); + expect(plainImages[1].styles.width).toBe(DEFAULT_PLAIN_SIZE.width); + expect(plainImages[1].styles.height).toBe(DEFAULT_PLAIN_SIZE.height); + + }); + + it(`should display plain gallery grid layout`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + plainGalleryConfig: { + strategy: PlainGalleryStrategy.GRID, + layout: new GridLayout({width: '80px', height: '80px'}, {length: 2, wrap: true}) + } + }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const plainGallery: DebugElement = element.query(By.css('div.plain-container')); + expect(plainGallery.name).toBe('div'); + expect(plainGallery.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.plainGalleryContentTitle); + expect(plainGallery.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.plainGalleryContentAriaLabel); + expect(plainGallery.styles['flex-wrap']).toBe('wrap'); + + const plainImages: DebugElement[] = plainGallery.children; + expect(plainImages.length).toBe(IMAGES.length); + }); + + it(`should display plain gallery with anchor tags based of input images`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + plainGalleryConfig: { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout( + {width: DEFAULT_PLAIN_SIZE.width, height: DEFAULT_PLAIN_SIZE.height}, + {length: IMAGES.length, wrap: true}, + 'flex-start' + ), + advanced: {aTags: true, additionalBackground: '50% 50% / cover'} + } + }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const plainGallery: DebugElement = element.query(By.css('div.plain-container')); + expect(plainGallery.name).toBe('div'); + expect(plainGallery.attributes.ksDirection).toBe(''); + expect(plainGallery.attributes.ksWrap).toBe(''); + expect(plainGallery.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.plainGalleryContentTitle); + expect(plainGallery.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.plainGalleryContentAriaLabel); + // expect(plainGallery.styles['flex-direction']).toBe('row'); + expect(plainGallery.styles['justify-content']).toBe('flex-start'); + + const plainImages: DebugElement[] = plainGallery.children; + expect(plainImages.length).toBe(IMAGES.length); + expect(plainImages[0].name).toBe('a'); + // expect(plainImages[0].attributes['href']).toBe('#'); + expect(plainImages[0].attributes.class).toBe('a-tag-image'); + // expect(plainImages[0].attributes['aria-label']).toBe(IMAGES[0].modal.ariaLabel); + expect(plainImages[0].properties.title).toBe('Image 1/5'); + expect(plainImages[0].properties.tabIndex).toBe(0); + expect(plainImages[0].styles.width).toBe(DEFAULT_PLAIN_SIZE.width); + expect(plainImages[0].styles.height).toBe(DEFAULT_PLAIN_SIZE.height); + expect(plainImages[0].styles.background).toBe(`url("${IMAGES[0].modal.img}") 50% 50% / cover`); + + expect(plainImages[1].name).toBe('a'); + // expect(plainImages[1].attributes['href']).toBe('#'); + expect(plainImages[1].attributes.class).toBe('a-tag-image'); + // expect(plainImages[1].attributes['aria-label']).toBe(IMAGES[0].modal.ariaLabel); + expect(plainImages[1].properties.title).toBe('Image 2/5 - Description 2'); + expect(plainImages[1].properties.tabIndex).toBe(0); + expect(plainImages[1].styles.width).toBe(DEFAULT_PLAIN_SIZE.width); + expect(plainImages[1].styles.height).toBe(DEFAULT_PLAIN_SIZE.height); + expect(plainImages[1].styles.background).toBe(`url("${IMAGES[1].modal.img}") 50% 50% / cover`); + + expect(plainImages[2].name).toBe('a'); + // expect(plainImages[2].attributes['href']).toBe('#'); + expect(plainImages[2].attributes.class).toBe('a-tag-image'); + // expect(plainImages[2].attributes['aria-label']).toBe(IMAGES[0].modal.ariaLabel); + expect(plainImages[2].properties.title).toBe(IMAGES[2].plain?.title); + expect(plainImages[2].properties.tabIndex).toBe(0); + expect(plainImages[2].styles.width).toBe(DEFAULT_PLAIN_SIZE.width); + expect(plainImages[2].styles.height).toBe(DEFAULT_PLAIN_SIZE.height); + expect(plainImages[2].styles.background).toBe(`url("${IMAGES[2].plain?.img}") 50% 50% / cover`); + + expect(plainImages[3].name).toBe('a'); + // expect(plainImages[3].attributes['href']).toBe('#'); + expect(plainImages[3].attributes.class).toBe('a-tag-image'); + // expect(plainImages[3].attributes['aria-label']).toBe(IMAGES[0].modal.ariaLabel); + expect(plainImages[3].properties.title).toBe('Image 4/5 - Description 4'); + expect(plainImages[3].properties.tabIndex).toBe(0); + expect(plainImages[3].styles.width).toBe(DEFAULT_PLAIN_SIZE.width); + expect(plainImages[3].styles.height).toBe(DEFAULT_PLAIN_SIZE.height); + expect(plainImages[3].styles.background).toBe(`url("${IMAGES[3].modal.img}") 50% 50% / cover`); + + expect(plainImages[4].name).toBe('a'); + // expect(plainImages[4].attributes['href']).toBe('#'); + expect(plainImages[4].attributes.class).toBe('a-tag-image'); + // expect(plainImages[4].attributes['aria-label']).toBe(IMAGES[0].modal.ariaLabel); + expect(plainImages[4].properties.title).toBe('Image 5/5'); + expect(plainImages[4].properties.tabIndex).toBe(0); + expect(plainImages[4].styles.width).toBe(DEFAULT_PLAIN_SIZE.width); + expect(plainImages[4].styles.height).toBe(DEFAULT_PLAIN_SIZE.height); + expect(plainImages[4].styles.background).toBe(`url("${IMAGES[4].plain?.img}") 50% 50% / cover`); + + comp.clickImage.subscribe((res: number) => { + expect(res).toBe(1); + }); + + plainImages[1].nativeElement.click(); + }); + + CUSTOM_SIZES.forEach((size: Size, index: number) => { + it(`should display plain gallery with anchor tags and custom sizes. Test i=${index}`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + plainGalleryConfig: { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout( + {width: size.width, height: size.height}, + {length: IMAGES.length, wrap: false}, + 'flex-start' + ), + advanced: {aTags: true, additionalBackground: '50% 50% / cover'} + } + }); + comp.id = GALLERY_ID; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const plainGallery: DebugElement = element.query(By.css('div.plain-container')); + const plainImages: DebugElement[] = plainGallery.children; + expect(plainImages.length).toBe(IMAGES.length); + expect(plainImages[0].styles.width).toBe(size.width); + expect(plainImages[0].styles.height).toBe(size.height); + expect(plainImages[1].styles.width).toBe(size.width); + expect(plainImages[1].styles.height).toBe(size.height); + expect(plainImages[2].styles.width).toBe(size.width); + expect(plainImages[2].styles.height).toBe(size.height); + expect(plainImages[3].styles.width).toBe(size.width); + expect(plainImages[3].styles.height).toBe(size.height); + expect(plainImages[4].styles.width).toBe(size.width); + expect(plainImages[4].styles.height).toBe(size.height); + }); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/plain-gallery/plain-gallery.component.ts b/projects/ks89/angular-modal-gallery/src/lib/components/plain-gallery/plain-gallery.component.ts new file mode 100644 index 00000000..682d25f1 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/plain-gallery/plain-gallery.component.ts @@ -0,0 +1,308 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChange, SimpleChanges } from '@angular/core'; + +import { AccessibilityConfig } from '../../model/accessibility.interface'; +import { Image } from '../../model/image.class'; +import { Size } from '../../model/size.interface'; +import { GridLayout, LineLayout, PlainGalleryConfig, PlainGalleryStrategy } from '../../model/plain-gallery-config.interface'; + +import { getIndex } from '../../utils/image.util'; +import { ConfigService } from '../../services/config.service'; +import { NEXT } from '../../utils/user-input.util'; +import { AccessibleComponent } from '../accessible.component'; +import { PlainLibConfig, LibConfig } from '../../model/lib-config.interface'; + +/** + * Component with the gallery of thumbs. + * In receives an array of Images, a boolean to show/hide + * the gallery (feature used by imagePointer) and a config + * object to customize the behaviour of this component. + * Also, it emits click events as outputs. + */ +@Component({ + selector: 'ks-plain-gallery', + styleUrls: ['plain-gallery.scss'], + templateUrl: 'plain-gallery.html', + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: false +}) +export class PlainGalleryComponent extends AccessibleComponent implements OnInit, OnChanges { + /** + * Unique id (>=0) of the current instance of this library. This is required when you are using + * the service to call modal gallery. + */ + @Input() + id: number | undefined; + + /** + * Array of `Image` that represent the model of this library with all images, thumbs and so on. + */ + @Input() + images: Image[] = []; + /** + * PlainLibConfig object to configure plain-gallery. + */ + @Input() + config: PlainLibConfig | undefined; + + /** + * Output to emit an event when an image is clicked. + */ + @Output() + clickImage: EventEmitter = new EventEmitter(); + + /** + * Object of type `PlainGalleryConfig` to configure the plain gallery. + */ + plainGalleryConfig: PlainGalleryConfig | undefined; + + /** + * Object of type `AccessibilityConfig` to init custom accessibility features. + * For instance, it contains titles, alt texts, aria-labels and so on. + */ + accessibilityConfig: AccessibilityConfig | undefined; + + /** + * Bi-dimensional array of `Image` object to store images to display as plain gallery. + * [] by default. + */ + imageGrid: Image[][] = []; + /** + * Size object used in the template to resize images. + */ + size: Size | undefined; + /** + * Boolean passed as input to `ks-wrap` directive to configure flex-wrap css property. + * However it's not enough, because you need to limit the width using `widthStyle` public variable. + * For more info check https://developer.mozilla.org/it/docs/Web/CSS/flex-wrap + */ + wrapStyle = false; + /** + * String passed as input to `ks-wrap` directive to set width to be able to force overflow. + * In this way, `wrapStyle` (flex-wrap css property) will be used as requested. + */ + widthStyle = ''; + /** + * String passed as input to `ks-direction` directive to set the flex-direction css property. + * For more info check https://developer.mozilla.org/it/docs/Web/CSS/flex-direction + */ + directionStyle: string | undefined; + /** + * String passed as input to `ks-direction` directive to set the justify-content css property. + * For more info check https://developer.mozilla.org/it/docs/Web/CSS/justify-content + */ + justifyStyle: string | undefined; + + constructor(private configService: ConfigService) { + super(); + } + + /** + * Method ´ngOnInit´ to init both `configPlainGallery` calling `initPlainGalleryConfig()` + * and `imageGrid invoking `initImageGrid()`. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called only one time!!! + */ + ngOnInit(): void { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + this.configService.setConfig(this.id, this.config); + + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + this.accessibilityConfig = libConfig.accessibilityConfig; + this.plainGalleryConfig = libConfig.plainGalleryConfig; + this.initImageGrid(); + } + + /** + * Method ´ngOnChanges´ to update both `imageGrid` and`plainGalleryConfig`. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called when any data-bound property of a directive changes!!! + */ + ngOnChanges(changes: SimpleChanges): void { + if (this.id === null || this.id === undefined) { + throw new Error('Internal library error - id must be defined'); + } + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + + const imagesChange: SimpleChange = changes.images; + const configChange: SimpleChange = changes.config; + // I'm using !change.firstChange because the first time will be called both onInit and onChange and I don't + // want to execute initialization two times. + if ( + configChange && + !configChange.firstChange && + (configChange.previousValue !== configChange.currentValue || (!configChange.previousValue && !configChange.currentValue)) + ) { + this.plainGalleryConfig = libConfig.plainGalleryConfig; + // this.configPlainGallery = this.initPlainGalleryConfig(); + } + if (imagesChange && !imagesChange.firstChange && imagesChange.previousValue !== imagesChange.currentValue) { + this.initImageGrid(); + } + } + + /** + * Method called when you click on an image of the plain (or inline) gallery. + * This will emit the show event with the image as payload. + * @param Image img is the Image to show + */ + showModalGalleryByImage(img: Image): void { + const index: number = this.images.findIndex((val: Image) => val && img && val.id === img.id); + this.showModalGallery(index); + } + + /** + * Method called when you navigate between images. + * This will emit the show event with the image as payload. + * @param KeyboardEvent event that triggered the navigation + * @param Image img is the Image to show + */ + onNavigationEvent(event: KeyboardEvent, img: Image): void { + const result: number = super.handleImageEvent(event); + if (result === NEXT) { + this.showModalGalleryByImage(img); + } + } + + /** + * Method to get `alt attribute`. + * `alt` specifies an alternate text for an image, if the image cannot be displayed. + * @param Image image to get its alt description. + * @returns string alt description of the image + */ + getAltPlainDescriptionByImage(image: Image): string { + if (!image) { + return ''; + } + return image.plain && image.plain.description ? image.plain.description : `Image ${getIndex(image, this.images) + 1}`; + } + + /** + * Method to get the title for an image. + * @param Image image to get its title + * @returns string the title of the input image + */ + getTitleDisplay(image: Image): string { + let description = ''; + + if (image.plain && image.plain.description) { + description = image.plain.description; + } else if (image.modal && image.modal.description) { + description = image.modal.description; + } + + const currentIndex: number = getIndex(image, this.images); + const prevDescription: string = 'Image ' + (currentIndex + 1) + '/' + this.images.length; + let currImgDescription: string = description ? description : ''; + + if (currImgDescription !== '') { + currImgDescription = ' - ' + currImgDescription; + } + return prevDescription + currImgDescription; + } + + /** + * Method used in the template to track ids in ngFor. + * @param number index of the array + * @param Image item of the array + * @returns number the id of the item + */ + trackById(index: number, item: Image): number { + return item.id; + } + + /** + * Method called when you click on an image of the plain (or inline) gallery. + * This will emit the show event with the index number as payload. + * @param number index of the clicked image + */ + private showModalGallery(index: number): void { + this.clickImage.emit(index); + } + + /** + * Private method to init both `imageGrid` and other style variables, + * based on the layout type. + */ + private initImageGrid(): void { + if (!this.plainGalleryConfig) { + throw new Error('Internal library error - plainGalleryConfig must be defined'); + } + + // reset the array to prevent issues in case of GridLayout + this.imageGrid = []; + + if (this.plainGalleryConfig.layout instanceof LineLayout) { + const layout: LineLayout = this.plainGalleryConfig.layout; + const row: Image[] = this.images.filter((val: Image, i: number) => i < layout.breakConfig.length || layout.breakConfig.length === -1); + this.imageGrid = [row]; + + this.size = this.plainGalleryConfig.layout.size; + + switch (this.plainGalleryConfig.strategy) { + case PlainGalleryStrategy.ROW: + this.directionStyle = 'row'; + break; + case PlainGalleryStrategy.COLUMN: + this.directionStyle = 'column'; + this.wrapStyle = layout.breakConfig.wrap; + break; + } + this.justifyStyle = layout.justify; + } + + if (this.plainGalleryConfig.layout instanceof GridLayout) { + const layout: GridLayout = this.plainGalleryConfig.layout; + const count: number = Math.ceil(this.images.length / layout.breakConfig.length); + let start = 0; + let end: number = layout.breakConfig.length - 1; + + for (let j = 0; j < count; j++) { + const row: Image[] = this.images.filter((val: Image, i: number) => i >= start && i <= end); + this.imageGrid.push(row); + start = end + 1; + end = start + layout.breakConfig.length - 1; + } + + this.size = this.plainGalleryConfig.layout.size; + + const pixels: number = +layout.size.width.replace('px', ''); + + this.widthStyle = pixels * layout.breakConfig.length + pixels / 2 + 'px'; + this.wrapStyle = layout.breakConfig.wrap; + + this.directionStyle = 'row'; + } + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/plain-gallery/plain-gallery.html b/projects/ks89/angular-modal-gallery/src/lib/components/plain-gallery/plain-gallery.html new file mode 100644 index 00000000..5737719a --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/plain-gallery/plain-gallery.html @@ -0,0 +1,42 @@ +
+ + + + + + {{imgCol.plain?.alt! ? imgCol.plain?.alt! : getAltPlainDescriptionByImage(imgCol)}} + + + + + + + + + + + +
+ diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/plain-gallery/plain-gallery.scss b/projects/ks89/angular-modal-gallery/src/lib/components/plain-gallery/plain-gallery.scss new file mode 100644 index 00000000..ca1d085e --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/plain-gallery/plain-gallery.scss @@ -0,0 +1,59 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +$plain-image-margin-left: 2px; +$plain-image-margin-right: 2px; +$plain-image-width: 50px; + +$plain-a-tag-image-margin-left: 2px; +$plain-a-tag-image-margin-right: 2px; +$plain-a-tag-image-margin-top: 2px; +$plain-a-tag-image-margin-bottom: 2px; + +.plain-container { + align-items: center; + display: flex; + + // defined via Angular using DirectionDirective + //flex-direction: row; + //justify-content: flex-start; + + .image { + cursor: pointer; + height: auto; + margin-top: $plain-a-tag-image-margin-top; + margin-bottom: $plain-a-tag-image-margin-bottom; + margin-left: $plain-image-margin-left; + margin-right: $plain-image-margin-right; + width: $plain-image-width; + } + + .a-tag-image { + cursor: pointer; + //width: 50px; + //height: auto; + margin-top: $plain-a-tag-image-margin-top; + margin-bottom: $plain-a-tag-image-margin-bottom; + margin-left: $plain-a-tag-image-margin-left; + margin-right: $plain-a-tag-image-margin-right; + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/previews-arrows.scss b/projects/ks89/angular-modal-gallery/src/lib/components/previews-arrows.scss new file mode 100644 index 00000000..fa77506b --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/previews-arrows.scss @@ -0,0 +1,63 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// all svgs are converted to base 64 with this website http://b64.io/ + +$arrow-preview-image-width: 15px; +$arrow-preview-image-height: 15px; +$arrow-preview-image-bg-size: 15px; +$arrow-preview-image-no-active-opacity: .5; +$arrow-preview-transition: .5s; + +.arrow-preview-image { + width: $arrow-preview-image-width; + height: $arrow-preview-image-height; + opacity: $arrow-preview-image-no-active-opacity; +} + +.empty-arrow-preview-image { + @extend .arrow-preview-image; + background: black; + opacity: 0; +} + +.left-arrow-preview-image { + @extend .arrow-preview-image; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ3Ny4xNzUgNDc3LjE3NSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDc3LjE3NSA0NzcuMTc1OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij48Zz48cGF0aCBkPSJNMTQ1LjE4OCwyMzguNTc1bDIxNS41LTIxNS41YzUuMy01LjMsNS4zLTEzLjgsMC0xOS4xcy0xMy44LTUuMy0xOS4xLDBsLTIyNS4xLDIyNS4xYy01LjMsNS4zLTUuMywxMy44LDAsMTkuMWwyMjUuMSwyMjUgICBjMi42LDIuNiw2LjEsNCw5LjUsNHM2LjktMS4zLDkuNS00YzUuMy01LjMsNS4zLTEzLjgsMC0xOS4xTDE0NS4xODgsMjM4LjU3NXoiIGZpbGw9IiNGRkZGRkYiLz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+"); + background-size: $arrow-preview-image-bg-size; + transition: all $arrow-preview-transition; + + &:hover { + transform: scale(1.2); + } +} + +.right-arrow-preview-image { + @extend .arrow-preview-image; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ3Ny4xNzUgNDc3LjE3NSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDc3LjE3NSA0NzcuMTc1OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij48Zz48cGF0aCBkPSJNMzYwLjczMSwyMjkuMDc1bC0yMjUuMS0yMjUuMWMtNS4zLTUuMy0xMy44LTUuMy0xOS4xLDBzLTUuMywxMy44LDAsMTkuMWwyMTUuNSwyMTUuNWwtMjE1LjUsMjE1LjUgICBjLTUuMyw1LjMtNS4zLDEzLjgsMCwxOS4xYzIuNiwyLjYsNi4xLDQsOS41LDRjMy40LDAsNi45LTEuMyw5LjUtNGwyMjUuMS0yMjUuMUMzNjUuOTMxLDI0Mi44NzUsMzY1LjkzMSwyMzQuMjc1LDM2MC43MzEsMjI5LjA3NXogICAiIGZpbGw9IiNGRkZGRkYiLz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+"); + background-size: $arrow-preview-image-bg-size; + transition: all $arrow-preview-transition; + + &:hover { + transform: scale(1.2); + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/previews/previews.component.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/components/previews/previews.component.spec.ts new file mode 100644 index 00000000..ec2be9a0 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/previews/previews.component.spec.ts @@ -0,0 +1,1024 @@ +/* + * Copyright (C) 2017-2024 Stefano Cappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, DebugElement, SimpleChanges, TemplateRef, ViewChild } from '@angular/core'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; + +import { KS_DEFAULT_ACCESSIBILITY_CONFIG } from '../../components/accessibility-default'; +import { FallbackImageDirective } from '../../directives/fallback-image.directive'; +import { SizeDirective } from '../../directives/size.directive'; +import { AccessibilityConfig } from '../../model/accessibility.interface'; +import { Action } from '../../model/action.enum'; +import { InternalLibImage } from '../../model/image-internal.class'; +import { ImageModalEvent, ModalImage, PlainImage } from '../../model/image.class'; +import { PreviewConfig } from '../../model/preview-config.interface'; +import { Size } from '../../model/size.interface'; +import { SlideConfig } from '../../model/slide-config.interface'; +import { ConfigService } from '../../services/config.service'; +import { KS_DEFAULT_SIZE } from '../upper-buttons/upper-buttons-default'; +import { PreviewsComponent } from './previews.component'; + + + +interface NavigationTestData { + initial: { + start: number, + end: number, + activeIndex: number + }; + expected: { + start: number, + end: number, + activeIndex: number + }; +} + +const GALLERY_ID = 1; + +let comp: PreviewsComponent; +let fixture: ComponentFixture; + +const CUSTOM_ACCESSIBILITY: AccessibilityConfig = Object.assign({}, KS_DEFAULT_ACCESSIBILITY_CONFIG); +CUSTOM_ACCESSIBILITY.previewsContainerAriaLabel = 'custom previewsContainerAriaLabel'; +CUSTOM_ACCESSIBILITY.previewsContainerTitle = 'custom previewsContainerTitle'; +CUSTOM_ACCESSIBILITY.previewScrollNextAriaLabel = 'custom previewScrollNextAriaLabel'; +CUSTOM_ACCESSIBILITY.previewScrollNextTitle = 'custom previewScrollNextTitle'; +CUSTOM_ACCESSIBILITY.previewScrollPrevAriaLabel = 'custom previewScrollPrevAriaLabel'; +CUSTOM_ACCESSIBILITY.previewScrollPrevTitle = 'custom previewScrollPrevTitle'; + +const DEFAULT_PREVIEW_SIZE: Size = {height: '50px', width: 'auto'}; +const CUSTOM_SIZE: Size = {height: '40px', width: '40px'}; +const CUSTOM_SIZE_AUTO_HEIGHT: Size = {height: 'auto', width: '40px'}; +const CUSTOM_SIZE_AUTO_WIDTH: Size = {height: '40px', width: 'auto'}; +const CUSTOM_SIZES: Size[] = [CUSTOM_SIZE, CUSTOM_SIZE_AUTO_HEIGHT, CUSTOM_SIZE_AUTO_WIDTH]; + +const PREVIEWS_CONFIG_VISIBLE: PreviewConfig = {visible: true}; +const SLIDE_CONFIG_INFINITE: SlideConfig = {infinite: true}; +const PREVIEWS_CONFIG_HIDDEN: PreviewConfig = {visible: false}; + +const SLIDE_CONFIG: SlideConfig = {infinite: false, sidePreviews: {show: true, size: KS_DEFAULT_SIZE}}; + + +const IMAGES: InternalLibImage[] = [ + new InternalLibImage(0, { + // modal + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new InternalLibImage(1, { + // modal + img: '../assets/images/gallery/img2.png', + description: 'Description 2' + }), + new InternalLibImage( + 2, + { + // modal + img: '../assets/images/gallery/img3.jpg', + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + // plain + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new InternalLibImage(3, { + // modal + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new InternalLibImage( + 4, + { + // modal + img: '../assets/images/gallery/img5.jpg' + }, + { + // plain + img: '../assets/images/gallery/thumbs/img5.jpg' + } + ) +]; + +const IMAGES_CUSTOM_ACCESSIBILITY: InternalLibImage[] = IMAGES.map((image: InternalLibImage) => { + const newImage: InternalLibImage = Object.assign({}, image); + newImage.modal.title = 'custom accessibility title'; + newImage.modal.alt = 'custom accessibility alt'; + newImage.modal.ariaLabel = 'custom accessibility ariaLabel'; + return newImage; +}); + +const NAVIGATION_NEXT_PREVIEWS: NavigationTestData[] = [ + { + initial: {start: 0, end: 3, activeIndex: 0}, + expected: {start: 1, end: 4, activeIndex: 0} + }, + { + initial: {start: 1, end: 4, activeIndex: 0}, + expected: {start: 2, end: 5, activeIndex: 0} + } +]; + +const NAVIGATION_PREV_PREVIEWS: NavigationTestData[] = [ + { + initial: {start: 2, end: 5, activeIndex: 0}, + expected: {start: 1, end: 4, activeIndex: 0} + }, + { + initial: {start: 1, end: 4, activeIndex: 0}, + expected: {start: 0, end: 3, activeIndex: 0} + } +]; + +function checkArrows(arrows: DebugElement[], first: boolean, last: boolean, + accessibility: AccessibilityConfig = KS_DEFAULT_ACCESSIBILITY_CONFIG): void { + const prevArrowClass = first ? 'inside empty-arrow-preview-image' : 'inside left-arrow-preview-image'; + const nextArrowClass = last ? 'inside empty-arrow-preview-image' : 'inside right-arrow-preview-image'; + expect(arrows.length).toBe(2); + expect(arrows[0].attributes.class).toBe('nav-left'); + expect(arrows[0].attributes.role).toBe('button'); + expect(arrows[0].attributes['aria-label']).toBe(accessibility.previewScrollPrevAriaLabel); + expect(arrows[0].properties.tabIndex).toBe(first ? -1 : 0); // because with the first image, prev arrow is hidden + expect(arrows[0].children[0].attributes['aria-hidden']).toBe('true'); + expect(arrows[0].children[0].properties.title).toBe(accessibility.previewScrollPrevTitle); + expect(containsClasses(arrows[0].children[0].properties.className, prevArrowClass)).toBeTrue(); + expect(arrows[1].attributes.class).toBe('nav-right'); + expect(arrows[1].attributes.role).toBe('button'); + expect(arrows[1].attributes['aria-label']).toBe(accessibility.previewScrollNextAriaLabel); + expect(arrows[1].properties.tabIndex).toBe(last ? -1 : 0); + expect(arrows[1].children[0].attributes['aria-hidden']).toBe('true'); + expect(arrows[1].children[0].properties.title).toBe(accessibility.previewScrollNextTitle); + expect(containsClasses(arrows[1].children[0].properties.className, nextArrowClass)).toBeTrue(); +} + +function checkPreview(previewElement: DebugElement, previewImage: InternalLibImage, isActive: boolean, size: Size = DEFAULT_PREVIEW_SIZE): void { + const currentPlainImg: PlainImage | undefined = previewImage.plain; + const currentModalImg: ModalImage | undefined = previewImage.modal; + expect(previewElement.name).toBe('img'); + expect(previewElement.attributes.role).toBe('img'); + expect(previewElement.attributes['aria-label']).toBe(currentModalImg.ariaLabel ? currentModalImg.ariaLabel : ''); + expect(previewElement.attributes.ksSize).toBe(''); + if (size) { + // I don't know why I cannot retrieve styles from btnDebugElement, so I decided to + // get elements via Directive. + const sizes: DebugElement[] = fixture.debugElement.queryAll(By.directive(SizeDirective)); + let width = ''; + let height = ''; + const split: string[] | undefined = sizes[0].attributes.style?.split(';'); + if (!split) { + throw new Error('This test expects to check styles applied by ksSize directive'); + } + split.pop(); // remove last element because it contains '' + split.forEach((item: string) => { + if (item.trim().startsWith('width:')) { + width = item.replace('width:', '').trim(); + } else if (item.trim().startsWith('height:')) { + height = item.replace('height:', '').trim(); + } + }); + expect(width).toBe(size.width); + expect(height).toBe(size.height); + } + // expect(previewElement.properties.className).toBe('inside preview-image ' + (isActive ? 'active' : '')); + expect(previewElement.properties.src).toBe(currentPlainImg && currentPlainImg.img ? currentPlainImg.img : currentModalImg.img); + expect(previewElement.properties.title).toBe(currentModalImg.title ? currentModalImg.title : ''); + expect(previewElement.properties.alt).toBe(currentModalImg.alt ? currentModalImg.alt : ''); + expect(previewElement.properties.tabIndex).toBe(0); + // expect(previewElement.properties.className).toBe('inside preview-image ' + (isActive ? 'active' : '')); +} + +function containsClasses(actualClasses: string, expectedClasses: string): boolean { + const actual: string[] = actualClasses.split(' '); + const expected: string[] = expectedClasses.split(' '); + let count = 0; + if (actual.length !== expected.length) { + return false; + } + expected.forEach((item: string) => { + if (actual.includes(item)) { + count++; + } + }); + return count === expected.length; +} + +function checkPreviewStateAfterClick(previews: DebugElement[], prevValue: InternalLibImage, currValue: InternalLibImage, + start: number, end: number, activeIndex: number = 0): void { + fixture.detectChanges(); + // comp.ngOnChanges({ + // currentImage: { + // previousValue: prevValue, + // currentValue: currValue, + // firstChange: false, + // isFirstChange: () => false + // } + // }); + expect(comp.start).toBe(start); + expect(comp.end).toBe(end); + expect(comp.previews).toEqual(IMAGES.slice(start, end)); +} + +/** + * A template-providing component to test the template-driven previews customization. + */ + @Component({ + template: ` + +
example
+
+`, + standalone: false +}) +class PreviewsTemplateComponent0 { + @ViewChild('template') templateRef?: TemplateRef; +} + +/** + * A template-providing component to test the template-driven previews customization (using default template). + */ +@Component({ + template: ` + +
+ +
+
+`, + standalone: false +}) +class PreviewsTemplateComponent1 { + @ViewChild('template') templateRef?: TemplateRef; +} + +function initTestBed(): void { + TestBed.configureTestingModule({ + declarations: [ + PreviewsComponent, + SizeDirective, + FallbackImageDirective, + PreviewsTemplateComponent0, + PreviewsTemplateComponent1, + ] + }).overrideComponent(PreviewsComponent, { + set: { + providers: [ + { + provide: ConfigService, + useClass: ConfigService + } + ] + } + }); +} + +describe('PreviewsComponent', () => { + beforeEach(() => { + initTestBed(); + fixture = TestBed.createComponent(PreviewsComponent); + comp = fixture.componentInstance; + }); + + it('should instantiate it', () => expect(comp).not.toBeNull()); + + describe('---YES---', () => { + + it(`should display previews (first one is active) based of input images`, () => { + const initialActiveImage = 0; + const numOfPreviews = 3; + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + previewConfig: PREVIEWS_CONFIG_VISIBLE, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + slideConfig: SLIDE_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[initialActiveImage]; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const arrows: DebugElement[] = element.queryAll(By.css('a')); + checkArrows(arrows, true, false); + + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + + const previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + + const previewImages: InternalLibImage[] = IMAGES.slice(initialActiveImage, numOfPreviews); + + for (let i = 0; i < previewImages.length; i++) { + checkPreview(previews[i], previewImages[i], i === 0, DEFAULT_PREVIEW_SIZE); + } + }); + + it(`should display previews (one in the middle is active) based of input images`, () => { + // in this example I choose the third image (index = 2) as the current one + const initialActiveImage = 2; // you can use every value except for 0 and the last one + const numOfPreviews = 3; + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + previewConfig: PREVIEWS_CONFIG_VISIBLE, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + slideConfig: SLIDE_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[initialActiveImage]; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const arrows: DebugElement[] = element.queryAll(By.css('a')); + checkArrows(arrows, false, false); + + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + + const previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + + const previewImages: InternalLibImage[] = IMAGES.slice(initialActiveImage - 1, initialActiveImage - 1 + numOfPreviews); + + for (let i = 0; i < previewImages.length; i++) { + checkPreview(previews[i], previewImages[i], i === 1, DEFAULT_PREVIEW_SIZE); + } + }); + + it(`should display previews (last one is active) based of input images`, () => { + // in this example I choose the last image as the current one + const initialActiveImage = IMAGES.length - 1; + const numOfPreviews = 3; + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + previewConfig: PREVIEWS_CONFIG_VISIBLE, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + slideConfig: SLIDE_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[initialActiveImage]; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const arrows: DebugElement[] = element.queryAll(By.css('a')); + checkArrows(arrows, false, true); + + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + + const previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + + const previewImages: InternalLibImage[] = IMAGES.slice(initialActiveImage + 1 - numOfPreviews, initialActiveImage + 1); + + for (let i = 0; i < previewImages.length; i++) { + checkPreview(previews[i], previewImages[i], i === 2, DEFAULT_PREVIEW_SIZE); + } + }); + + it(`should display previews with custom accessibility`, () => { + const initialActiveImage = 0; + const numOfPreviews = 3; + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + previewConfig: PREVIEWS_CONFIG_VISIBLE, + // custom accessibility for container and arrows, but not for previews + accessibilityConfig: CUSTOM_ACCESSIBILITY, + slideConfig: SLIDE_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES_CUSTOM_ACCESSIBILITY[initialActiveImage]; + comp.images = IMAGES_CUSTOM_ACCESSIBILITY; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const arrows: DebugElement[] = element.queryAll(By.css('a')); + checkArrows(arrows, true, false, CUSTOM_ACCESSIBILITY); + + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(CUSTOM_ACCESSIBILITY.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(CUSTOM_ACCESSIBILITY.previewsContainerTitle); + + const previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + + const previewImages: InternalLibImage[] = IMAGES.slice(initialActiveImage, numOfPreviews); + + for (let i = 0; i < previewImages.length; i++) { + checkPreview(previews[i], previewImages[i], i === 0, DEFAULT_PREVIEW_SIZE); + } + }); + + it(`should display a custom number of previews without navigation arrows`, () => { + const initialActiveImage = 0; + const numOfPreviews = 2; + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + previewConfig: {visible: true, number: 2, arrows: false}, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + slideConfig: SLIDE_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[initialActiveImage]; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const arrows: DebugElement[] = element.queryAll(By.css('a')); + expect(arrows.length).toBe(2); + checkArrows(arrows, true, true); + + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + + const previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + + const previewImages: InternalLibImage[] = IMAGES.slice(initialActiveImage, numOfPreviews); + + for (let i = 0; i < previewImages.length; i++) { + checkPreview(previews[i], previewImages[i], i === 0, DEFAULT_PREVIEW_SIZE); + } + }); + + CUSTOM_SIZES.forEach((size: Size, index: number) => { + it(`should display previews with custom sizes. Index i=${index}`, () => { + const initialActiveImage = 0; + const numOfPreviews = 3; + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + previewConfig: {visible: true, size}, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + slideConfig: SLIDE_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[initialActiveImage]; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const arrows: DebugElement[] = element.queryAll(By.css('a')); + checkArrows(arrows, true, false); + + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + + const previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + + const previewImages: InternalLibImage[] = IMAGES.slice(initialActiveImage, numOfPreviews); + + for (let i = 0; i < previewImages.length; i++) { + checkPreview(previews[i], previewImages[i], i === 0, size); + } + }); + }); + + it(`should display previews (first one is active) and click on the second one`, () => { + const initialActiveImage = 0; + const numOfPreviews = 3; + const afterClickActivePreview = 0; + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + previewConfig: PREVIEWS_CONFIG_VISIBLE, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + slideConfig: SLIDE_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[initialActiveImage]; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + comp.clickPreview.subscribe((res: ImageModalEvent) => { + const event: ImageModalEvent = new ImageModalEvent(GALLERY_ID, Action.CLICK, afterClickActivePreview); + expect(res).toEqual(event); + }); + + const element: DebugElement = fixture.debugElement; + + const arrows: DebugElement[] = element.queryAll(By.css('a')); + checkArrows(arrows, true, false); + + const previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + + const previewImages: InternalLibImage[] = IMAGES.slice(initialActiveImage, numOfPreviews); + + for (let i = 0; i < previewImages.length; i++) { + checkPreview(previews[i], previewImages[i], i === 0, DEFAULT_PREVIEW_SIZE); + } + + previews[afterClickActivePreview].nativeElement.click(); + }); + + // TODO + // it(`should display previews (first one is active) and go to the second one with keyboard`, () => { + // const initialActivePreview = 0; + // const afterClickActivePreview = 0; + // const numberOfVisiblePreviews = 3; + // comp.previewConfig = PREVIEWS_CONFIG_VISIBLE; + // comp.accessibilityConfig = KS_DEFAULT_ACCESSIBILITY_CONFIG; + // comp.currentImage = IMAGES[initialActivePreview]; + // comp.images = IMAGES; + // comp.slideConfig = SLIDE_CONFIG; + // comp.ngOnInit(); + // fixture.detectChanges(); + // + // comp.clickPreview.subscribe((res: InternalLibImage) => { + // fail('I should go here'); + // expect(res).toEqual(IMAGES[afterClickActivePreview]); + // }); + // + // const element: DebugElement = fixture.debugElement; + // + // const arrows: DebugElement[] = element.queryAll(By.css('a')); + // checkArrows(arrows, true, false); + // + // const previews: DebugElement[] = element.queryAll(By.css('img')); + // expect(previews.length).toBe(numberOfVisiblePreviews); + // + // previews.forEach((preview: DebugElement, index: number) => { + // checkPreviewDefault(preview, initialActivePreview, index); + // }); + // + // previews[afterClickActivePreview].nativeElement.focus(); + // previews[afterClickActivePreview].triggerEventHandler('keyup', {keyCode: 32}); + // fixture.detectChanges(); + // }); + + NAVIGATION_NEXT_PREVIEWS.forEach((val: NavigationTestData, index: number) => { + it(`should navigate previews clicking on left arrow. Test i=${index}`, waitForAsync(() => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + previewConfig: PREVIEWS_CONFIG_VISIBLE, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + slideConfig: SLIDE_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[val.initial.activeIndex]; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(3); + + const arrows: DebugElement[] = element.queryAll(By.css('a')); + expect(arrows.length).toBe(2); + + spyOn(comp, 'onNavigationEvent').and.callThrough(); + + if (index !== 0) { + arrows[1].nativeElement.click(); + fixture.detectChanges(); + } + + expect(comp.start).toBe(val.initial.start); + expect(comp.end).toBe(val.initial.end); + expect(comp.previews).toEqual(IMAGES.slice(val.initial.start, val.initial.end)); + + if (index === 0) { + checkArrows(arrows, true, false); + } else { + checkArrows(arrows, false, false); + } + + arrows[1].nativeElement.click(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(comp.onNavigationEvent).toHaveBeenCalled(); + expect(comp.start).toBe(val.expected.start); + expect(comp.end).toBe(val.expected.end); + expect(comp.previews).toEqual(IMAGES.slice(val.expected.start, val.expected.end)); + if (index === 0) { + checkArrows(arrows, false, false); + } else { + checkArrows(arrows, false, true); + } + }); + })); + }); + + // TODO + // NAVIGATION_PREV_PREVIEWS.forEach((val: NavigationTestData, index: number) => { + // it(`should navigate back previews clicking on right arrow. Test i=${index}`, waitForAsync(() => { + // comp.previewConfig = PREVIEWS_CONFIG_VISIBLE; + // comp.accessibilityConfig = KS_DEFAULT_ACCESSIBILITY_CONFIG; + // comp.currentImage = IMAGES[val.initial.activeIndex]; + // comp.images = IMAGES; + // comp.slideConfig = SLIDE_CONFIG; + // comp.ngOnInit(); + // fixture.detectChanges(); + // + // const element: DebugElement = fixture.debugElement; + // + // const previews: DebugElement[] = element.queryAll(By.css('img')); + // expect(previews.length).toBe(3); + // + // const arrows: DebugElement[] = element.queryAll(By.css('a')); + // expect(arrows.length).toBe(2); + // + // spyOn(comp, 'onNavigationEvent').and.callThrough(); + // + // if (index !== 0) { + // arrows[0].nativeElement.click(); + // fixture.detectChanges(); + // } + // + // expect(comp.start).toBe(val.initial.start); + // expect(comp.end).toBe(val.initial.end); + // expect(comp.previews).toEqual(IMAGES.slice(val.initial.start, val.initial.end)); + // + // if (index === 0) { + // checkArrows(arrows, false, true); + // } else { + // checkArrows(arrows, false, false); + // } + // + // arrows[0].nativeElement.click(); + // + // fixture.whenStable().then(() => { + // fixture.detectChanges(); + // expect(comp.onNavigationEvent).toHaveBeenCalled(); + // expect(comp.start).toBe(val.expected.start); + // expect(comp.end).toBe(val.expected.end); + // expect(comp.previews).toEqual(IMAGES.slice(val.expected.start, val.expected.end)); + // if (index === 0) { + // checkArrows(arrows, false, false); + // } else { + // checkArrows(arrows, true, false); + // } + // }); + // })); + // }); + + [SLIDE_CONFIG, SLIDE_CONFIG_INFINITE].forEach((slideConfig: SlideConfig, index: number) => { + it(`should navigate next/prev clicking on images for all SlideConfigs. Test i=${index}`, waitForAsync(() => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + previewConfig: PREVIEWS_CONFIG_VISIBLE, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + slideConfig + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[0]; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + let previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(3); + + const arrows: DebugElement[] = element.queryAll(By.css('a')); + expect(arrows.length).toBe(2); + + spyOn(comp, 'onImageEvent').and.callThrough(); + + let images: InternalLibImage[]; + + // this should change the current preview triggering ngOnChanges to navigate next/prev + // however this is a unit testing and I cannot use modal-gallery.component, + // so I have to simulate this behaviour manually + previews[0].nativeElement.click(); + checkPreviewStateAfterClick(previews, IMAGES[0], IMAGES[0], 0, 3, 0); + images = IMAGES.slice(0, 3); + for (let i = 0; i < images.length; i++) { + checkPreview(previews[i], images[i], i === 0, DEFAULT_PREVIEW_SIZE); + } + + fixture.detectChanges(); + + previews = element.queryAll(By.css('img')); + + // previews[1].nativeElement.click(); + comp.ngOnChanges({ + currentImage: { + previousValue: IMAGES[0], + currentValue: IMAGES[1], + firstChange: false, + isFirstChange: () => false + } + } as SimpleChanges); + checkPreviewStateAfterClick(previews, IMAGES[0], IMAGES[1], 0, 3, 1); + // images = IMAGES.slice(0, 3); + // for (let i = 0; i < images.length; i++) { + // checkPreview(previews[i], images[i], i === 1, DEFAULT_PREVIEW_SIZE); + // } + // images = IMAGESò.slice(1, 4); + // for (let i = 0; i < images.length; i++) { + // checkPreview(previews[i], images[i], i === 2, DEFAULT_PREVIEW_SIZE); + // } + previews = element.queryAll(By.css('img')); + fixture.detectChanges(); + // previews[2].nativeElement.click(); + comp.ngOnChanges({ + currentImage: { + previousValue: IMAGES[1], + currentValue: IMAGES[2], + firstChange: false, + isFirstChange: () => false + } + } as SimpleChanges); + checkPreviewStateAfterClick(previews, IMAGES[1], IMAGES[2], 1, 4, 2); + + previews = element.queryAll(By.css('img')); + fixture.detectChanges(); + // previews[2].nativeElement.click(); + comp.ngOnChanges({ + currentImage: { + previousValue: IMAGES[3], + currentValue: IMAGES[4], + firstChange: false, + isFirstChange: () => false + } + } as SimpleChanges); + checkPreviewStateAfterClick(previews, IMAGES[3], IMAGES[4], 2, 5, 4); + + previews = element.queryAll(By.css('img')); + fixture.detectChanges(); + previews[2].nativeElement.click(); + checkPreviewStateAfterClick(previews, IMAGES[4], IMAGES[4], 2, 5, 5); + })); + }); + + it(`should use a custom template to render the previews`, () => { + const templateComponentFixture = TestBed.createComponent(PreviewsTemplateComponent0); + const templateComponent = templateComponentFixture.debugElement.componentInstance as PreviewsTemplateComponent0; + templateComponentFixture.detectChanges(); + const templateRef = templateComponent.templateRef; + const initialActiveImage = 0; + const numOfPreviews = 3; + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + previewConfig: PREVIEWS_CONFIG_VISIBLE, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + slideConfig: SLIDE_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[initialActiveImage]; + comp.images = IMAGES; + comp.customTemplate = templateRef; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const arrows: DebugElement[] = element.queryAll(By.css('a')); + checkArrows(arrows, true, false); + + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + const previews: DebugElement[] = element.queryAll(By.css('.my-own-template')); + expect(previews.length).toBe(numOfPreviews); + }); + + it(`should use a custom template to render the previews (using default template)`, () => { + const templateComponentFixture = TestBed.createComponent(PreviewsTemplateComponent1); + const templateComponent = templateComponentFixture.debugElement.componentInstance as PreviewsTemplateComponent1; + templateComponentFixture.detectChanges(); + const templateRef = templateComponent.templateRef; + const initialActiveImage = 0; + const numOfPreviews = 3; + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + previewConfig: PREVIEWS_CONFIG_VISIBLE, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + slideConfig: SLIDE_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[initialActiveImage]; + comp.images = IMAGES; + comp.customTemplate = templateRef; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const arrows: DebugElement[] = element.queryAll(By.css('a')); + checkArrows(arrows, true, false); + + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + + const previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(numOfPreviews); + + const previewImages: InternalLibImage[] = IMAGES.slice(initialActiveImage, numOfPreviews); + + for (let i = 0; i < previewImages.length; i++) { + checkPreview(previews[i], previewImages[i], i === 0, DEFAULT_PREVIEW_SIZE); + } + }); + + [4, 5].forEach((previewNumber: number) => { + it(`should display a constant number of previews (${previewNumber}), independent of current image index`, waitForAsync(() => { + const configService = fixture.debugElement.injector.get(ConfigService); + const previewConfig = Object.assign({}, PREVIEWS_CONFIG_VISIBLE, { number: previewNumber }) as PreviewConfig; + configService.setConfig(GALLERY_ID, { + previewConfig, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + slideConfig: SLIDE_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[0]; + comp.images = IMAGES; + comp.ngOnInit(); + expect(comp.previews.length).toBe(previewNumber); + + // click on the second picture + comp.currentImage = IMAGES[1]; // set component input + comp.ngOnChanges({ // trigger changes manually (not done automatically in tests) + currentImage: { + previousValue: IMAGES[0], + currentValue: IMAGES[1], + firstChange: false, + isFirstChange: () => false + } + } as SimpleChanges); + // at the time of writing this test, a change is detected within 'images', yet with the same value + comp.ngOnChanges({ + images: { + previousValue: IMAGES, + currentValue: IMAGES, + firstChange: false, + isFirstChange: () => false + } + } as SimpleChanges); + expect(comp.previews.length).toBe(previewNumber); + + // click on the third picture + comp.currentImage = IMAGES[2]; // set component input + comp.ngOnChanges({ // trigger changes manually (not done automatically in tests) + currentImage: { + previousValue: IMAGES[1], + currentValue: IMAGES[2], + firstChange: false, + isFirstChange: () => false + } + } as SimpleChanges); + // at the time of writing this test, a change is detected within 'images', yet with the same value + comp.ngOnChanges({ + images: { + previousValue: IMAGES, + currentValue: IMAGES, + firstChange: false, + isFirstChange: () => false + } + } as SimpleChanges); + expect(comp.previews.length).toBe(previewNumber); + })); + }); + + it('should allow to navigate previews from first to last and back', () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + previewConfig: PREVIEWS_CONFIG_VISIBLE, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + slideConfig: SLIDE_CONFIG + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[0]; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + const element: DebugElement = fixture.debugElement; + let previews: DebugElement[] = element.queryAll(By.css('img')); + + const leftArrow = element.query(By.css('a.nav-left')).nativeElement as HTMLAnchorElement; + const rightArrow = element.query(By.css('a.nav-right')).nativeElement as HTMLAnchorElement; + checkPreviewStateAfterClick(previews, IMAGES[0], IMAGES[0], 0, 3, 0); + + // click right until the last preview is reached + rightArrow.click(); + checkPreviewStateAfterClick(previews, IMAGES[0], IMAGES[0], 1, 4, 0); + rightArrow.click(); + checkPreviewStateAfterClick(previews, IMAGES[0], IMAGES[0], 2, 5, 0); + // click left until the first preview is reached + leftArrow.click(); + checkPreviewStateAfterClick(previews, IMAGES[0], IMAGES[0], 1, 4, 0); + leftArrow.click(); + checkPreviewStateAfterClick(previews, IMAGES[0], IMAGES[0], 0, 3, 0); + // click right again and check previews have changed accordingly + rightArrow.click(); + checkPreviewStateAfterClick(previews, IMAGES[0], IMAGES[0], 1, 4, 0); + + }); + + it('should always display previews navigation arrows, in infinite sliding mode (nbPreviews < nbImages)', () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + previewConfig: PREVIEWS_CONFIG_VISIBLE, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + slideConfig: SLIDE_CONFIG_INFINITE + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[0]; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + const element: DebugElement = fixture.debugElement; + const leftArrow = element.query(By.css('a.nav-left')).nativeElement as HTMLAnchorElement; + const rightArrow = element.query(By.css('a.nav-right')).nativeElement as HTMLAnchorElement; + let leftArrowDiv = element.query(By.css('a.nav-left > div')).nativeElement as HTMLAnchorElement; + let rightArrowDiv = element.query(By.css('a.nav-right > div')).nativeElement as HTMLAnchorElement; + // check that arrows are initially visible + expect(leftArrowDiv.classList).toContain('left-arrow-preview-image'); + expect(rightArrowDiv.classList).toContain('right-arrow-preview-image'); + // click right until the last preview is reached, each time check that arrows are visible + rightArrow.click(); + fixture.detectChanges(); + leftArrowDiv = element.query(By.css('a.nav-left > div')).nativeElement as HTMLAnchorElement; + rightArrowDiv = element.query(By.css('a.nav-right > div')).nativeElement as HTMLAnchorElement; + expect(leftArrowDiv.classList).toContain('left-arrow-preview-image'); + expect(rightArrowDiv.classList).toContain('right-arrow-preview-image'); + rightArrow.click(); + fixture.detectChanges(); + leftArrowDiv = element.query(By.css('a.nav-left > div')).nativeElement as HTMLAnchorElement; + rightArrowDiv = element.query(By.css('a.nav-right > div')).nativeElement as HTMLAnchorElement; + expect(leftArrowDiv.classList).toContain('left-arrow-preview-image'); + expect(rightArrowDiv.classList).toContain('right-arrow-preview-image'); + }); + + }); + + describe('---NO---', () => { + it(`shouldn't display previews because visibility is false`, () => { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, { + previewConfig: PREVIEWS_CONFIG_HIDDEN + }); + comp.id = GALLERY_ID; + comp.currentImage = IMAGES[0]; + comp.images = IMAGES; + comp.ngOnInit(); + fixture.detectChanges(); + + const element: DebugElement = fixture.debugElement; + + const arrows: DebugElement[] = element.queryAll(By.css('a')); + expect(arrows.length).toBe(0); + + const previewsContainer: DebugElement = element.query(By.css('nav.previews-container')); + expect(previewsContainer.name).toBe('nav'); + // null because input accessibility is not provided in this test + expect(previewsContainer.attributes['aria-label']).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerAriaLabel); + expect(previewsContainer.properties.title).toBe(KS_DEFAULT_ACCESSIBILITY_CONFIG.previewsContainerTitle); + + const previews: DebugElement[] = element.queryAll(By.css('img')); + expect(previews.length).toBe(0); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/previews/previews.component.ts b/projects/ks89/angular-modal-gallery/src/lib/components/previews/previews.component.ts new file mode 100644 index 00000000..f9dd2927 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/previews/previews.component.ts @@ -0,0 +1,325 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { ChangeDetectionStrategy, Component, ContentChild, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChange, SimpleChanges, TemplateRef } from '@angular/core'; + +import { AccessibleComponent } from '../accessible.component'; + +import { AccessibilityConfig } from '../../model/accessibility.interface'; +import { Image, ImageEvent, ImageModalEvent } from '../../model/image.class'; +import { InternalLibImage } from '../../model/image-internal.class'; +import { PreviewConfig } from '../../model/preview-config.interface'; +import { SlideConfig } from '../../model/slide-config.interface'; + +import { NEXT, PREV } from '../../utils/user-input.util'; +import { getIndex } from '../../utils/image.util'; +import { Action } from '../../model/action.enum'; +import { ConfigService, DEFAULT_PREVIEW_SIZE } from '../../services/config.service'; +import { Size } from '../../model/size.interface'; +import { LibConfig } from '../../model/lib-config.interface'; + +/** + * Component with image previews + */ +@Component({ + selector: 'ks-previews', + styleUrls: ['previews.scss', '../previews-arrows.scss'], + templateUrl: 'previews.html', + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: false +}) +export class PreviewsComponent extends AccessibleComponent implements OnInit, OnChanges { + /** + * Unique id (>=0) of the current instance of this library. This is required when you are using + * the service to call modal gallery. + */ + @Input() + id!: number; + /** + * Object of type `InternalLibImage` that represent the visible image. + */ + @Input() + currentImage!: InternalLibImage; + /** + * Array of `InternalLibImage` that represent the model of this library with all images, + * thumbs and so on. + */ + @Input() + images!: InternalLibImage[]; + + /** + * Optional template reference for the rendering of previews. + * Template may access following context variables: + * - preview: the `Image` object + * - defaultTemplate: the template used by default to render the preview (in case the need is to wrap it) + */ + @Input() + customTemplate?: TemplateRef; + + /** + * Output to emit the clicked preview. The payload contains the `ImageEvent` associated to the clicked preview. + */ + @Output() + clickPreview: EventEmitter = new EventEmitter(); + + /** + * Object of type `AccessibilityConfig` to init custom accessibility features. + * For instance, it contains titles, alt texts, aria-labels and so on. + */ + accessibilityConfig: AccessibilityConfig | undefined; + /** + * Object of type `SlideConfig` to get `infinite sliding`. + */ + slideConfig: SlideConfig | undefined; + /** + * Object of type `PreviewConfig` to init PreviewsComponent's features. + * For instance, it contains a param to show/hide this component, sizes. + */ + previewConfig: PreviewConfig | undefined; + /** + * Enum of type `Action` that represents a mouse click on a button. + * Declared here to be used inside the template. + */ + clickAction: Action = Action.CLICK; + /** + * Enum of type `Action` that represents a keyboard action. + * Declared here to be used inside the template. + */ + keyboardAction: Action = Action.KEYBOARD; + /** + * Array of `InternalLibImage` exposed to the template. This field is initialized + * applying transformations, default values and so on to the input of the same type. + */ + previews: InternalLibImage[] = []; + /** + * Start index (included) of the input images used to display previews. + */ + // @ts-ignore + start: number; + /** + * End index (excluded) of the input images used to display previews. + */ + // @ts-ignore + end: number; + + defaultPreviewSize: Size = DEFAULT_PREVIEW_SIZE; + + constructor(private configService: ConfigService) { + super(); + } + + /** + * Method ´ngOnInit´ to build `configPreview` applying a default value and also to + * init the `previews` array. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called only one time!!! + */ + ngOnInit(): void { + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig) { + throw new Error('Internal library error - libConfig must be defined'); + } + this.accessibilityConfig = libConfig.accessibilityConfig; + this.slideConfig = libConfig.slideConfig; + this.previewConfig = libConfig.previewConfig; + this.initPreviews(this.currentImage, this.images); + } + + /** + * Method to check if an image is active (i.e. a preview image). + * @param InternalLibImage preview is an image to check if it's active or not + * @returns boolean true if is active, false otherwise + */ + isActive(preview: InternalLibImage): boolean { + if (!preview) { + return false; + } + return preview.id === this.currentImage.id; + } + + /** + * Method ´ngOnChanges´ to update `previews` array. + * Also, both `start` and `end` local variables will be updated accordingly. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called when any data-bound property of a directive changes!!! + */ + ngOnChanges(changes: SimpleChanges): void { + + let currentImage = changes.currentImage?.currentValue ?? this.currentImage; + let images = changes.images?.currentValue ?? this.images; + + if(this.previewConfig && currentImage && images) { + this.initPreviews( currentImage, images); + } + } + + /** + * Method called by events from both keyboard and mouse on a preview. + * This will trigger the `clickpreview` output with the input preview as its payload. + * @param InternalLibImage preview that triggered this method + * @param KeyboardEvent | MouseEvent event payload + * @param Action action that triggered the source event or `Action.NORMAL` if not specified + */ + onImageEvent(preview: InternalLibImage, event: KeyboardEvent | MouseEvent, action: Action = Action.NORMAL): void { + // It's suggested to stop propagation of the event, so the + // Cdk background will not catch a click and close the modal (like it does on Windows Chrome/FF). + event?.stopPropagation(); + if (!this.previewConfig || !this.previewConfig.clickable) { + return; + } + const result: number = super.handleImageEvent(event); + if (result === NEXT || result === PREV) { + this.clickPreview.emit(new ImageModalEvent(this.id, action, getIndex(preview, this.images))); + } + } + + /** + * Method called by events from both keyboard and mouse on a navigation arrow. + * It also emits an event to specify which arrow. + * @param string direction of the navigation that can be either 'next' or 'prev' + * @param KeyboardEvent | MouseEvent event payload + * @param Action action that triggered the source event or `Action.NORMAL` if not specified + */ + onNavigationEvent(direction: string, event: KeyboardEvent | MouseEvent, action: Action = Action.NORMAL): void { + const result: number = super.handleNavigationEvent(direction, event); + if (result === NEXT) { + this.next(); + } else if (result === PREV) { + this.previous(); + } + } + + /** + * Method used in the template to track ids in ngFor. + * @param number index of the array + * @param Image item of the array + * @returns number the id of the item + */ + trackById(index: number, item: Image): number { + return item.id; + } + + /** + * Indicates if the previews 'left arrow' should be displayed or not. + * @returns + */ + displayLeftPreviewsArrow(): boolean { + // Don't show arrows if requested previews number equals or is greated than total number of imgaes + if(this.previewConfig?.number !== undefined && this.images && this.previewConfig?.number >= this.images?.length) { + return false; + } + return (this.previewConfig?.arrows && this.start > 0) || !!this.slideConfig?.infinite; + } + + /** + * Indicates if the previews 'right arrow' should be displayed or not. + * @returns + */ + displayRightPreviewsArrow(): boolean { + // Don't show arrows if requested previews number equals or is greated than total number of imgaes + if(this.previewConfig?.number !== undefined && this.images && this.previewConfig?.number >= this.images?.length) { + return false; + } + return (this.previewConfig?.arrows && this.images && this.end < this.images.length) || !!this.slideConfig?.infinite; + } + + /** + * Private method to init previews based on the currentImage and the full array of images. + * The current image in mandatory to show always the current preview (as highlighted). + * @param InternalLibImage currentImage to decide how to show previews, because I always want to see the current image as highlighted + * @param InternalLibImage[] images is the array of all images. + */ + private initPreviews(currentImage: InternalLibImage, images: InternalLibImage[]): void { + this.setIndexesPreviews(currentImage, images); + this.previews = images.filter((img: InternalLibImage, i: number) => i >= this.start && i < this.end); + } + + /** + * Private method to update both `start` and `end` based on the currentImage. + */ + private setIndexesPreviews(currentImage: InternalLibImage, images: InternalLibImage[]): void { + if (!this.previewConfig || !images || !currentImage) { + throw new Error('Internal library error - previewConfig, currentImage and images must be defined'); + } + const previewsNumber = this.previewConfig.number as number; + let start = getIndex(currentImage, images) - Math.floor(previewsNumber / 2); + // start is, at a minimum, the first index + if(start < 0) start = 0; + // end index + let end = start + previewsNumber; + // end is, at a maximum, the last index + if(end > images.length) { + start -= end - images.length; + if(start < 0) start = 0; // start is, at a minimum, the first index + end = images.length; + } + this.start = start; + this.end = end; + } + + /** + * Private method to update the visible previews navigating to the right (next). + */ + private next(): void { + if (!this.previewConfig) { + throw new Error('Internal library error - previewConfig must be defined'); + } + if(this.end >= this.images.length) { + // check if nextImage should be blocked + const preventSliding = !!this.slideConfig && this.slideConfig.infinite === false; + if(preventSliding) { + return; + } + this.start = 0; + } else { + this.start++; + } + this.end = this.start + Math.min((this.previewConfig.number as number), this.images.length); + + this.previews = this.images.filter((img: InternalLibImage, i: number) => i >= this.start && i < this.end); + } + + /** + * Private method to update the visible previews navigating to the left (previous). + */ + private previous(): void { + if (!this.previewConfig) { + throw new Error('Internal library error - previewConfig must be defined'); + } + if(this.start <= 0) { + // check if prevImage should be blocked + const preventSliding = !!this.slideConfig && this.slideConfig.infinite === false; + if(preventSliding) { + return; + } + this.end = this.images.length; + } else { + this.end--; + } + this.start = this.end - Math.min((this.previewConfig.number as number), this.images.length); + + this.previews = this.images.filter((img: InternalLibImage, i: number) => i >= this.start && i < this.end); + } + +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/previews/previews.html b/projects/ks89/angular-modal-gallery/src/lib/components/previews/previews.html new file mode 100644 index 00000000..fbb45535 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/previews/previews.html @@ -0,0 +1,55 @@ + diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/previews/previews.scss b/projects/ks89/angular-modal-gallery/src/lib/components/previews/previews.scss new file mode 100644 index 00000000..b7332ff2 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/previews/previews.scss @@ -0,0 +1,190 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// all svgs are converted to base 64 with this website http://b64.io/ + +$container-margin-bottom: 15px; +$preview-image-fade-in-time: .8s; +$preview-image-side-margin: 2px; +$preview-container-fade-in-time: .8s; +$preview-image-opacity: .7; +$preview-image-hover-opacity: 1; +$preview-image-active-opacity: 1; +$preview-image-height: 50px; + +$nav-color: #919191; +$nav-animation-time: 1s; +$nav-transition-time: .5s; +$nav-side-margin: 10px; + +// Mobile +@media only screen and (max-width: 767px), only screen and (max-device-width: 767px) { + .previews-container { + display: none; + + > .preview-image { + display: none; + } + + > .nav-left { + display: none; + } + + > .nav-right { + display: none; + } + } + + // TODO improve this code + .previews-container.mobile-visible { + align-items: center; + animation: fadein-semi-visible08 $preview-container-fade-in-time; + display: flex; + flex-direction: row; + justify-content: center; + margin-bottom: $container-margin-bottom; + + > .nav-left { + display: flex; + } + + > .nav-right { + display: flex; + } + + > .preview-image { + cursor: pointer; + display: flex; + margin-left: $preview-image-side-margin; + margin-right: $preview-image-side-margin; + opacity: $preview-image-opacity; + height: $preview-image-height; + //animation: fadein-semi-visible08 $preview-image-fade-in-time; + + &.active { + opacity: $preview-image-hover-opacity; + //animation: fadein-visible $preview-image-fade-in-time; + } + + &.unclickable { + cursor: not-allowed; + } + + &:hover { + opacity: $preview-image-active-opacity; + transition: all .5s ease; + transition-property: opacity; + } + } + } +} + +// Others except for Modile +@media only screen and (min-device-width: 768px) { + .previews-container { + align-items: center; + animation: fadein-semi-visible08 $preview-container-fade-in-time; + display: flex; + flex-direction: row; + justify-content: center; + margin-bottom: $container-margin-bottom; + + .preview-container { + margin-left: $preview-image-side-margin; + margin-right: $preview-image-side-margin; + cursor: pointer; + &.unclickable { + cursor: not-allowed; + } + .preview-image { + opacity: $preview-image-opacity; + height: $preview-image-height; + //animation: fadein-semi-visible08 $preview-image-fade-in-time; + + &.active { + opacity: $preview-image-hover-opacity; + //animation: fadein-visible $preview-image-fade-in-time; + } + + &:hover { + opacity: $preview-image-active-opacity; + transition: all .5s ease; + transition-property: opacity; + } + } + } + + .nav { + color: $nav-color; + //animation: animatezoom $nav-animation-time; + cursor: pointer; + transition: all $nav-transition-time; + + &:hover { + transform: scale(1.1); + } + } + + > .nav-left { + @extend .nav; + margin-right: $nav-side-margin; + } + + > .nav-right { + @extend .nav; + margin-left: $nav-side-margin; + } + } +} + +// other useful media queries +///** Tablet **/ +//@media only screen and (min-width: 768px) and (max-width: 1024px) +///** Tablet (landscape) **/ +//@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: landscape) +///** Desktops or greater **/ +//@media only screen and (min-device-width: 1025px) + +@mixin fadein($opacity-from, $opacity-to) { + from { + opacity: $opacity-from; + } + to { + opacity: $opacity-to; + } +} + +@keyframes fadein-visible { + @include fadein(0, 1); +} + +@keyframes fadein-semi-visible05 { + @include fadein(0, .5); +} + +@keyframes fadein-semi-visible08 { + @include fadein(0, .8); +} + +@keyframes fadein-semi-visible09 { + @include fadein(0, .9); +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/upper-buttons/upper-buttons-default.ts b/projects/ks89/angular-modal-gallery/src/lib/components/upper-buttons/upper-buttons-default.ts new file mode 100644 index 00000000..5c672fcb --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/upper-buttons/upper-buttons-default.ts @@ -0,0 +1,82 @@ +import { ButtonConfig, ButtonType } from '../../model/buttons-config.interface'; +import { Size } from '../../model/size.interface'; + +/** + * Default button size object + */ +export const KS_DEFAULT_SIZE: Size = { height: 'auto', width: '30px' }; + +/** + * Default close button object + */ +export const KS_DEFAULT_BTN_CLOSE: ButtonConfig = { + className: 'close-image', + size: KS_DEFAULT_SIZE, + type: ButtonType.CLOSE, + title: 'Close this modal image gallery', + ariaLabel: 'Close this modal image gallery' +}; + +/** + * Default download button object + */ +export const KS_DEFAULT_BTN_DOWNLOAD: ButtonConfig = { + className: 'download-image', + size: KS_DEFAULT_SIZE, + type: ButtonType.DOWNLOAD, + title: 'Download the current image', + ariaLabel: 'Download the current image' +}; + +/** + * Default exturl button object + */ +export const KS_DEFAULT_BTN_EXTURL: ButtonConfig = { + className: 'ext-url-image', + size: KS_DEFAULT_SIZE, + type: ButtonType.EXTURL, + title: 'Navigate the current image', + ariaLabel: 'Navigate the current image' +}; +// /** +// * Default refresh button object +// */ +// export const KS_DEFAULT_BTN_REFRESH: ButtonConfig = { +// className: 'refresh-image', +// size: KS_DEFAULT_SIZE, +// type: ButtonType.REFRESH, +// title: 'Refresh all images', +// ariaLabel: 'Refresh all images' +// }; + +/** + * Default delete button object + */ +export const KS_DEFAULT_BTN_DELETE: ButtonConfig = { + className: 'delete-image', + size: KS_DEFAULT_SIZE, + type: ButtonType.DELETE, + title: 'Delete the current image', + ariaLabel: 'Delete the current image' +}; + +/** + * Default full-screen button object + */ +export const KS_DEFAULT_BTN_FULL_SCREEN: ButtonConfig = { + className: 'fullscreen-image', + size: KS_DEFAULT_SIZE, + type: ButtonType.FULLSCREEN, + title: 'Switch to full-screen', + ariaLabel: 'Switch to full-screen' +}; +/** + * Default rotate button object + */ +// export const KS_DEFAULT_BTN_ROTATE: ButtonConfig = { +// className: 'rotate-image', +// size: KS_DEFAULT_SIZE, +// type: ButtonType.ROTATE, +// title: 'Rotate clockwise of 90 degrees the current image', +// ariaLabel: 'Rotate clockwise of 90 degrees the current image' +// }; diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/upper-buttons/upper-buttons.component.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/components/upper-buttons/upper-buttons.component.spec.ts new file mode 100644 index 00000000..272e68d6 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/upper-buttons/upper-buttons.component.spec.ts @@ -0,0 +1,720 @@ +/* + * Copyright (C) 2017-2024 Stefano Cappa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DebugElement } from '@angular/core'; +import { By } from '@angular/platform-browser'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { InternalButtonConfig, UpperButtonsComponent } from './upper-buttons.component'; +import { Image } from '../../model/image.class'; +import { ButtonConfig, ButtonEvent, ButtonsConfig, ButtonsStrategy, ButtonType } from '../../model/buttons-config.interface'; +import { Size } from '../../model/size.interface'; +import { KS_DEFAULT_BTN_CLOSE, KS_DEFAULT_BTN_DELETE, KS_DEFAULT_BTN_DOWNLOAD, + KS_DEFAULT_BTN_EXTURL, KS_DEFAULT_BTN_FULL_SCREEN, KS_DEFAULT_SIZE } from './upper-buttons-default'; +import { Action } from '../../model/action.enum'; +import { ConfigService } from '../../services/config.service'; +import { SizeDirective } from '../../directives/size.directive'; + +let comp: UpperButtonsComponent; +let fixture: ComponentFixture; +const GALLERY_ID = 1; + +// const BAD_IMAGE: Image = new Image(0, null); + +const IMAGE_EXTURL: Image = new Image(0, { + img: '../../../../../apps/src/assets/images/gallery/img1.jpg', + description: 'Description 1', + extUrl: 'http://www.google.com' +}); + +const IMAGE_NO_EXTURL: Image = new Image(0, { + img: '../../../../../apps/src/assets/images/gallery/img1.jpg' +}); + +const NO_EXTURL_CASES: Image[] = [IMAGE_NO_EXTURL/*, BAD_IMAGE*/]; + +const CUSTOM_SIZE: Size = {height: '40px', width: '40px'}; +const CUSTOM_SIZE_AUTO_HEIGHT: Size = {height: 'auto', width: '40px'}; +const CUSTOM_SIZE_AUTO_WIDTH: Size = {height: '40px', width: 'auto'}; + +const UNKNOWN_STRATEGY = 6; +const UNKNOWN_BUTTON_TYPE = 99; + + +const CUSTOM_BTN: ButtonConfig = { + className: 'custom-image', + size: KS_DEFAULT_SIZE, + type: ButtonType.CUSTOM, + title: 'Custom title', + ariaLabel: 'Custom aria label' +}; + +const WRONG_TYPE_BTN: ButtonConfig = { + className: 'wrong-type-image', + size: KS_DEFAULT_SIZE, + // @ts-ignore + type: UNKNOWN_BUTTON_TYPE, + title: 'Custom wrong-type title', + ariaLabel: 'Custom wrong-type aria label' +}; + +const CUSTOM_FA_BUTTONS: ButtonConfig[] = [ + { + className: 'fa fa-plus white', + type: ButtonType.CUSTOM, + ariaLabel: 'custom plus aria label', + title: 'custom plus title', + fontSize: '20px' + }, + { + className: 'fa fa-trash white', + type: ButtonType.DELETE, + ariaLabel: 'custom delete aria label', + title: 'custom delete title', + fontSize: '20px' + }, + { + className: 'fa fa-close white', + type: ButtonType.CLOSE, + ariaLabel: 'custom close aria label', + title: 'custom close title', + fontSize: '20px' + }, + { + className: 'fa fa-download white', + type: ButtonType.DOWNLOAD, + ariaLabel: 'custom download aria label', + title: 'custom download title', + fontSize: '20px' + }, + { + className: 'fa fa-external-link white', + type: ButtonType.EXTURL, + ariaLabel: 'custom exturl aria label', + title: 'custom exturl title', + fontSize: '20px' + }]; + +const VISIBILITY_CASES: ButtonsConfig[] = [ + {visible: false, strategy: ButtonsStrategy.DEFAULT}, + {visible: false, strategy: ButtonsStrategy.SIMPLE}, + {visible: false, strategy: ButtonsStrategy.ADVANCED}, + {visible: false, strategy: ButtonsStrategy.FULL}, + {visible: false, strategy: ButtonsStrategy.CUSTOM} +]; + +const DEFAULT_CASES: ButtonsConfig[] = [ + {visible: true, strategy: ButtonsStrategy.DEFAULT}, + {visible: true, strategy: ButtonsStrategy.SIMPLE}, + {visible: true, strategy: ButtonsStrategy.ADVANCED}, + {visible: true, strategy: ButtonsStrategy.FULL} +]; + +const CUSTOM_NO_BUTTONS_CASES: ButtonsConfig[] = [{visible: true, strategy: ButtonsStrategy.CUSTOM}]; + +// should be ignored by the component and consider ButtonStrategy +const IGNORE_CUSTOM_CASES: ButtonsConfig[] = [ + {visible: true, strategy: ButtonsStrategy.DEFAULT, buttons: [CUSTOM_BTN]}, + {visible: true, strategy: ButtonsStrategy.SIMPLE, buttons: [CUSTOM_BTN]}, + {visible: true, strategy: ButtonsStrategy.ADVANCED, buttons: [CUSTOM_BTN]}, + {visible: true, strategy: ButtonsStrategy.FULL, buttons: [CUSTOM_BTN]} +]; + +const UNKNOWN_CASES: ButtonsConfig[] = [ + // @ts-ignore + {visible: true, strategy: UNKNOWN_STRATEGY, buttons: [CUSTOM_BTN]}, + // @ts-ignore + {visible: true, strategy: UNKNOWN_STRATEGY} +]; + +const CUSTOM_CASES: ButtonsConfig[] = [ + {visible: true, strategy: ButtonsStrategy.CUSTOM, buttons: [CUSTOM_BTN]}, + {visible: true, strategy: ButtonsStrategy.CUSTOM, buttons: [CUSTOM_BTN, CUSTOM_BTN]}, + { + visible: true, + strategy: ButtonsStrategy.CUSTOM, + buttons: [KS_DEFAULT_BTN_CLOSE, CUSTOM_BTN, CUSTOM_BTN, KS_DEFAULT_BTN_DOWNLOAD, KS_DEFAULT_BTN_DOWNLOAD] + }, + { + visible: true, + strategy: ButtonsStrategy.CUSTOM, + buttons: [KS_DEFAULT_BTN_DOWNLOAD, KS_DEFAULT_BTN_CLOSE, + KS_DEFAULT_BTN_DELETE, KS_DEFAULT_BTN_EXTURL, KS_DEFAULT_BTN_CLOSE] + } +]; + +const CUSTOM_SIZES: ButtonsConfig[] = [ + { + visible: true, strategy: ButtonsStrategy.CUSTOM, buttons: [ + buildBtnWithCustomSize(ButtonType.DOWNLOAD, CUSTOM_SIZE), buildBtnWithCustomSize(ButtonType.CLOSE, CUSTOM_SIZE), + buildBtnWithCustomSize(ButtonType.CUSTOM, CUSTOM_SIZE), buildBtnWithCustomSize(ButtonType.DELETE, CUSTOM_SIZE)] + }, + { + visible: true, strategy: ButtonsStrategy.CUSTOM, buttons: [ + buildBtnWithCustomSize(ButtonType.DOWNLOAD, CUSTOM_SIZE_AUTO_HEIGHT), buildBtnWithCustomSize(ButtonType.CLOSE, CUSTOM_SIZE_AUTO_HEIGHT), + buildBtnWithCustomSize(ButtonType.CUSTOM, CUSTOM_SIZE_AUTO_HEIGHT), buildBtnWithCustomSize(ButtonType.DELETE, CUSTOM_SIZE_AUTO_HEIGHT)] + }, + { + visible: true, strategy: ButtonsStrategy.CUSTOM, buttons: [ + buildBtnWithCustomSize(ButtonType.DOWNLOAD, CUSTOM_SIZE_AUTO_WIDTH), buildBtnWithCustomSize(ButtonType.CLOSE, CUSTOM_SIZE_AUTO_WIDTH), + buildBtnWithCustomSize(ButtonType.CUSTOM, CUSTOM_SIZE_AUTO_WIDTH), buildBtnWithCustomSize(ButtonType.DELETE, CUSTOM_SIZE_AUTO_WIDTH)] + } +]; + +const CUSTOM_FA_CASE: ButtonsConfig = {visible: true, strategy: ButtonsStrategy.CUSTOM, buttons: CUSTOM_FA_BUTTONS}; + +const NOT_VALID_BTN_TYPE_CASES: ButtonsConfig[] = [ + {visible: true, strategy: ButtonsStrategy.CUSTOM, buttons: [WRONG_TYPE_BTN]} +]; + +const EXTURL_BTN_NEW_TAB: ButtonConfig = Object.assign({}, KS_DEFAULT_BTN_EXTURL, {extUrlInNewTab: true}); + +const EXT_URL_IN_A_NEW_TAB_CASES: ButtonsConfig[] = [ + {visible: true, strategy: ButtonsStrategy.CUSTOM, buttons: [EXTURL_BTN_NEW_TAB]}, + {visible: true, strategy: ButtonsStrategy.CUSTOM, buttons: [CUSTOM_BTN, EXTURL_BTN_NEW_TAB]}, + { + visible: true, + strategy: ButtonsStrategy.CUSTOM, + buttons: [KS_DEFAULT_BTN_CLOSE, EXTURL_BTN_NEW_TAB, CUSTOM_BTN, KS_DEFAULT_BTN_DOWNLOAD, KS_DEFAULT_BTN_DOWNLOAD] + }, + { + visible: true, + strategy: ButtonsStrategy.CUSTOM, + buttons: [KS_DEFAULT_BTN_DOWNLOAD, KS_DEFAULT_BTN_CLOSE, KS_DEFAULT_BTN_DELETE, EXTURL_BTN_NEW_TAB] + } +]; + +function getButtonEvent(button: ButtonConfig): ButtonEvent { + return { + galleryId: GALLERY_ID, + button, + // upper-buttons.component always returns a null image to the main component, so I should test for a null + image: null, + action: Action.CLICK + }; +} + +function updateInputs(image: Image, configButtons: ButtonsConfig): void { + const configService = fixture.debugElement.injector.get(ConfigService); + configService.setConfig(GALLERY_ID, {buttonsConfig: configButtons}); + comp.id = GALLERY_ID; + comp.currentImage = image; + comp.ngOnInit(); + fixture.detectChanges(); +} + +function buildBtnWithCustomSize(btnType: ButtonType, size: Size): ButtonConfig { + switch (btnType) { + case ButtonType.CLOSE: + return Object.assign({}, KS_DEFAULT_BTN_CLOSE, {size}); + case ButtonType.DOWNLOAD: + return Object.assign({}, KS_DEFAULT_BTN_DOWNLOAD, {size}); + case ButtonType.EXTURL: + return Object.assign({}, KS_DEFAULT_BTN_EXTURL, {size}); + case ButtonType.DELETE: + return Object.assign({}, KS_DEFAULT_BTN_DELETE, {size}); + case ButtonType.FULLSCREEN: + return Object.assign({}, KS_DEFAULT_BTN_FULL_SCREEN, {size}); + case ButtonType.CUSTOM: + return Object.assign({}, CUSTOM_BTN, {size}); + default: + throw new Error('this test should run only with known button types'); + } +} + +function testCurrentHtmlBtn(btnDebugElement: DebugElement, btnIndex: number, size: Size, withFontAwesome: boolean = false): void { + if (!comp.buttons || !comp.buttons[btnIndex]) { + throw new Error('There is something wrong in this test, because currentButton must be defined!'); + } + const currentButton: InternalButtonConfig = comp.buttons[btnIndex] as InternalButtonConfig; + expect(btnDebugElement.name).toBe('a'); + expect(btnDebugElement.attributes.class).toBe('upper-button'); + expect(btnDebugElement.attributes.kssize).not.toBeNull(); + expect(btnDebugElement.attributes.sizeConfig).toBeUndefined(); + if (size) { + // I don't know why I cannot retrieve styles from btnDebugElement, so I decided to + // get elements via Directive. + const sizes: DebugElement[] = fixture.debugElement.queryAll(By.directive(SizeDirective)); + let width = ''; + let height = ''; + const split: string[] | undefined = sizes[0].attributes.style?.split(';'); + if (!split) { + throw new Error('This test expects to check styles applies by ksSize directive'); + } + split.pop(); // remove last element because it contains '' + if (!withFontAwesome) { + split.forEach((item: string) => { + if (item.trim().startsWith('width:')) { + width = item.replace('width:', '').trim(); + } else if (item.trim().startsWith('height:')) { + height = item.replace('height:', '').trim(); + } + }); + expect(width).toBe(size.width); + expect(height).toBe(size.height); + } else { + expect(split.length).toBe(1); + const fontSize: string = split[0].replace('font-size:', '').trim(); + // TODO improve this check because here I'm using always FA buttons with the same size + expect(fontSize).toBe(CUSTOM_FA_BUTTONS[0]?.fontSize as string); + } + } + expect(btnDebugElement.attributes['aria-label']).toBe(currentButton.ariaLabel ? currentButton.ariaLabel : null); + expect(btnDebugElement.attributes.role).toBe('button'); + expect(btnDebugElement.properties.tabIndex).toBe(0); + // expect(btnDebugElement.properties['hidden']).toBe(false); + + // console.log('btnDebugElement.attributes ' + btnIndex, btnDebugElement.attributes); + // console.log('btnDebugElement.properties ' + btnIndex, btnDebugElement.properties); + + if (currentButton.fontSize) { + expect(btnDebugElement.nativeElement.style.fontSize).toBe(currentButton.fontSize); + } + if (currentButton.size) { + expect(btnDebugElement.nativeElement.style.width).toBe(currentButton.size.width); + expect(btnDebugElement.nativeElement.style.height).toBe(currentButton.size.height); + } + + const childrenElements: DebugElement[] = btnDebugElement.children; + expect(childrenElements.length).toBe(1); + expect(childrenElements[0].attributes['aria-hidden']).toBe('true'); + expect(containsClasses(childrenElements[0].properties.className, currentButton.className + ' inside')).toBeTrue(); + expect(childrenElements[0].properties.title).toBe(currentButton.title); + // console.log('childrenElements.attributes ' + btnIndex, childrenElements[0].attributes); + // console.log('childrenElements.properties ' + btnIndex, childrenElements[0].properties); +} + +function containsClasses(actualClasses: string, expectedClasses: string): boolean { + const actual: string[] = actualClasses.split(' '); + const expected: string[] = expectedClasses.split(' '); + let count = 0; + if (actual.length !== expected.length) { + return false; + } + expected.forEach((item: string) => { + if (actual.includes(item)) { + count++; + } + }); + return count === expected.length; +} + +function testBtnNumberByStrategy(strategy: ButtonsStrategy, btnDebugElementsCount: number): void { + switch (strategy) { + case ButtonsStrategy.DEFAULT: + expect(btnDebugElementsCount).toBe(1); + break; + case ButtonsStrategy.SIMPLE: + expect(btnDebugElementsCount).toBe(2); + break; + case ButtonsStrategy.ADVANCED: + expect(btnDebugElementsCount).toBe(3); + break; + case ButtonsStrategy.FULL: + expect(btnDebugElementsCount).toBe(5); + break; + case ButtonsStrategy.CUSTOM: + // no constraints with custom strategy + break; + default: + fail('input strategy is not allowed'); + } +} + +function initTestBed(): void { + TestBed.configureTestingModule({ + declarations: [UpperButtonsComponent, SizeDirective] + }).overrideComponent(UpperButtonsComponent, { + set: { + providers: [ + { + provide: ConfigService, + useClass: ConfigService + } + ] + } + }); +} + +describe('UpperButtonsComponent', () => { + beforeEach(() => { + initTestBed(); + fixture = TestBed.createComponent(UpperButtonsComponent); + comp = fixture.componentInstance; + }); + + it('should instantiate it', () => expect(comp).not.toBeNull()); + + describe('---YES---', () => { + + DEFAULT_CASES.forEach((currentButtonConfig: ButtonsConfig, index: number) => { + it(`should display buttons for every default buttonConfigs and subscribe to click events. Test i=${index}`, () => { + updateInputs(IMAGE_EXTURL, currentButtonConfig); + + // expect a valid ButtonStrategy because passed to this test as input (via currentButtonConfig) + expect(ButtonsStrategy[currentButtonConfig.strategy]).not.toBeUndefined(); + + const element: DebugElement = fixture.debugElement; + const btns: DebugElement[] = element.queryAll(By.css('a.upper-button')); + + testBtnNumberByStrategy(currentButtonConfig.strategy, btns.length); + + comp.id = GALLERY_ID; + comp.closeButton.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_CLOSE)); + }); + comp.delete.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_DELETE)); + }); + comp.navigate.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_EXTURL)); + }); + comp.download.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_DOWNLOAD)); + }); + comp.fullscreen.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_FULL_SCREEN)); + }); + + // testing html elements, attributes and properties + btns.forEach((debugElement: DebugElement, btnIndex: number) => { + testCurrentHtmlBtn(debugElement, btnIndex, KS_DEFAULT_SIZE); + }); + + // iterate over all buttons from LEFT TO RIGHT + // clicking all of them + btns.forEach((debugElement: DebugElement) => { + debugElement.nativeElement.click(); + }); + }); + }); + + IGNORE_CUSTOM_CASES.forEach((currentButtonConfig: ButtonsConfig, index: number) => { + it(`should show default buttons ignoring custom ones passed as input, because strategy != CUSTOM. Test i=${index}`, () => { + updateInputs(IMAGE_EXTURL, currentButtonConfig); + + // expect a valid ButtonStrategy because passed to this test as input (via currentButtonConfig) + expect(ButtonsStrategy[currentButtonConfig.strategy]).not.toBeUndefined(); + + const element: DebugElement = fixture.debugElement; + const btns: DebugElement[] = element.queryAll(By.css('a.upper-button')); + + testBtnNumberByStrategy(currentButtonConfig.strategy, btns.length); + + comp.id = GALLERY_ID; + comp.closeButton.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_CLOSE)); + }); + comp.delete.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_DELETE)); + }); + comp.navigate.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_EXTURL)); + }); + comp.download.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_DOWNLOAD)); + }); + comp.fullscreen.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_FULL_SCREEN)); + }); + + // testing html elements, attributes and properties + btns.forEach((debugElement: DebugElement, btnIndex: number) => { + testCurrentHtmlBtn(debugElement, btnIndex, KS_DEFAULT_SIZE); + }); + + // iterate over all buttons from LEFT TO RIGHT + // clicking all of them + btns.forEach((debugElement: DebugElement) => { + debugElement.nativeElement.click(); + }); + }); + }); + + [DEFAULT_CASES[2], DEFAULT_CASES[3]].forEach((currentButtonConfig: ButtonsConfig, i: number) => { + NO_EXTURL_CASES.forEach((image: Image, j: number) => { + it(`shouldn't catch a navigate event, because either input image isn't valid or extUrl isn't defined. Test i=${i} j=${j}`, () => { + updateInputs(image, currentButtonConfig); + + // expect a valid ButtonStrategy because passed to this test as input (via currentButtonConfig) + expect(ButtonsStrategy[currentButtonConfig.strategy]).not.toBeUndefined(); + + const element: DebugElement = fixture.debugElement; + const btns: DebugElement[] = element.queryAll(By.css('a.upper-button')); + + testBtnNumberByStrategy(currentButtonConfig.strategy, btns.length); + + comp.id = GALLERY_ID; + comp.navigate.subscribe((res: ButtonEvent) => { + fail('navigate output should be never called, because input image is not valid or extUrl is not defined'); + }); + comp.closeButton.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_CLOSE)); + }); + comp.delete.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_DELETE)); + }); + comp.download.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_DOWNLOAD)); + }); + comp.fullscreen.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_FULL_SCREEN)); + }); + + // iterate over all buttons from LEFT TO RIGHT + // testing html elements, attributes and properties + btns.forEach((debugElement: DebugElement, btnIndex: number) => { + testCurrentHtmlBtn(debugElement, btnIndex, KS_DEFAULT_SIZE); + }); + + // iterate over all buttons from LEFT TO RIGHT + // clicking all of them + btns.forEach((debugElement: DebugElement) => { + debugElement.nativeElement.click(); + }); + }); + }); + }); + + CUSTOM_CASES.forEach((currentButtonConfig: ButtonsConfig, index: number) => { + it(`should display custom + default buttons and subscribe to click events. Test i=${index}`, () => { + updateInputs(IMAGE_EXTURL, currentButtonConfig); + + // expect a valid ButtonStrategy because passed to this test as input (via currentButtonConfig) + expect(ButtonsStrategy[currentButtonConfig.strategy]).not.toBeUndefined(); + + const element: DebugElement = fixture.debugElement; + const btns: DebugElement[] = element.queryAll(By.css('a.upper-button')); + + comp.id = GALLERY_ID; + comp.closeButton.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_CLOSE)); + }); + comp.delete.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_DELETE)); + }); + comp.navigate.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_EXTURL)); + }); + comp.download.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_DOWNLOAD)); + }); + comp.customEmit.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(CUSTOM_BTN)); + }); + comp.fullscreen.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_FULL_SCREEN)); + }); + + // iterate over all buttons from LEFT TO RIGHT + // testing html elements, attributes and properties + btns.forEach((debugElement: DebugElement, btnIndex: number) => { + testCurrentHtmlBtn(debugElement, btnIndex, KS_DEFAULT_SIZE); + }); + + // iterate over all buttons from LEFT TO RIGHT + // clicking all of them + btns.forEach((debugElement: DebugElement) => { + debugElement.nativeElement.click(); + }); + }); + }); + + EXT_URL_IN_A_NEW_TAB_CASES.forEach((currentButtonConfig: ButtonsConfig, index: number) => { + it(`should display buttons where extUrl buttons open extUrl in a new tab and subscribe to click events. Test i=${index}`, () => { + updateInputs(IMAGE_EXTURL, currentButtonConfig); + + // expect a valid ButtonStrategy because passed to this test as input (via currentButtonConfig) + expect(ButtonsStrategy[currentButtonConfig.strategy]).not.toBeUndefined(); + + const element: DebugElement = fixture.debugElement; + const btns: DebugElement[] = element.queryAll(By.css('a.upper-button')); + + comp.id = GALLERY_ID; + comp.closeButton.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_CLOSE)); + }); + comp.delete.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_DELETE)); + }); + comp.navigate.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(EXTURL_BTN_NEW_TAB)); + }); + comp.download.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_DOWNLOAD)); + }); + comp.customEmit.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(CUSTOM_BTN)); + }); + comp.fullscreen.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_FULL_SCREEN)); + }); + + // iterate over all buttons from LEFT TO RIGHT + // testing html elements, attributes and properties + btns.forEach((debugElement: DebugElement, btnIndex: number) => { + testCurrentHtmlBtn(debugElement, btnIndex, KS_DEFAULT_SIZE); + }); + + // iterate over all buttons from LEFT TO RIGHT + // clicking all of them + btns.forEach((debugElement: DebugElement) => { + debugElement.nativeElement.click(); + }); + }); + }); + + it(`should display custom buttons (with different types) with FontAwesome and subscribe to click events.`, () => { + updateInputs(IMAGE_EXTURL, CUSTOM_FA_CASE); + + // expect a valid ButtonStrategy because passed to this test as input (via currentButtonConfig) + expect(ButtonsStrategy[CUSTOM_FA_CASE.strategy]).not.toBeUndefined(); + + const element: DebugElement = fixture.debugElement; + const btns: DebugElement[] = element.queryAll(By.css('a.upper-button')); + + comp.id = GALLERY_ID; + comp.closeButton.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(CUSTOM_FA_BUTTONS[2])); + }); + comp.delete.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(CUSTOM_FA_BUTTONS[1])); + }); + comp.navigate.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(CUSTOM_FA_BUTTONS[4])); + }); + comp.download.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(CUSTOM_FA_BUTTONS[3])); + }); + comp.customEmit.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(CUSTOM_FA_BUTTONS[0])); + }); + + // iterate over all buttons from LEFT TO RIGHT + // testing html elements, attributes and properties + btns.forEach((debugElement: DebugElement, btnIndex: number) => { + testCurrentHtmlBtn(debugElement, btnIndex, KS_DEFAULT_SIZE, true); + }); + + // iterate over all buttons from LEFT TO RIGHT + // clicking all of them + btns.forEach((debugElement: DebugElement) => { + debugElement.nativeElement.click(); + }); + }); + + [CUSTOM_SIZES[0]].forEach((currentButtonConfig: ButtonsConfig, index: number) => { + it(`should display custom buttons (with different types) with custom sizes. Test i=${index}`, () => { + updateInputs(IMAGE_EXTURL, currentButtonConfig); + + // expect a valid ButtonStrategy because passed to this test as input (via currentButtonConfig) + expect(ButtonsStrategy[currentButtonConfig.strategy]).not.toBeUndefined(); + + const element: DebugElement = fixture.debugElement; + const btns: DebugElement[] = element.queryAll(By.css('a.upper-button')); + + // iterate over all buttons from LEFT TO RIGHT + // testing html elements, attributes and properties + btns.forEach((debugElement: DebugElement, btnIndex: number) => { + switch (index) { + case 0: + testCurrentHtmlBtn(debugElement, btnIndex, CUSTOM_SIZE); + break; + case 1: + testCurrentHtmlBtn(debugElement, btnIndex, CUSTOM_SIZE_AUTO_HEIGHT); + break; + case 2: + testCurrentHtmlBtn(debugElement, btnIndex, CUSTOM_SIZE_AUTO_WIDTH); + break; + } + }); + }); + }); + }); + + describe('---NO---', () => { + + VISIBILITY_CASES.forEach((currentButtonConfig: ButtonsConfig, index: number) => { + it(`shouldn't find any buttons, because visibility is false. Test i=${index}`, () => { + updateInputs(IMAGE_EXTURL, currentButtonConfig); + + // expect a valid ButtonStrategy because passed to this test as input (via currentButtonConfig) + expect(ButtonsStrategy[currentButtonConfig.strategy]).not.toBeUndefined(); + + const element: DebugElement = fixture.debugElement; + + const btnDebugElement: DebugElement = element.query(By.directive(SizeDirective)); + expect(btnDebugElement).toBeNull(); + + const btns: DebugElement[] = element.queryAll(By.css('a.upper-button')); + expect(btns.length).toBe(0); + }); + }); + + UNKNOWN_CASES.forEach((currentButtonConfig: ButtonsConfig, index: number) => { + it(`should display default buttons (DEFAULT strategy), because input strategy is unknown. Test i=${index}`, () => { + updateInputs(IMAGE_EXTURL, currentButtonConfig); + + // expect an UNKNOWN ButtonStrategy because passed to this test as input (via currentButtonConfig) + expect(ButtonsStrategy[currentButtonConfig.strategy]).toBeUndefined(); + + const element: DebugElement = fixture.debugElement; + const btns: DebugElement[] = element.queryAll(By.css('a.upper-button')); + expect(btns.length).toBe(1); + + comp.id = GALLERY_ID; + comp.closeButton.subscribe((res: ButtonEvent) => { + expect(res).toEqual(getButtonEvent(KS_DEFAULT_BTN_CLOSE)); + }); + + // iterate over all buttons from LEFT TO RIGHT + // testing html elements, attributes and properties + btns.forEach((debugElement: DebugElement, btnIndex: number) => { + testCurrentHtmlBtn(debugElement, btnIndex, KS_DEFAULT_SIZE); + }); + + // iterate over all buttons from LEFT TO RIGHT + // clicking all of them + btns.forEach((debugElement: DebugElement) => { + debugElement.nativeElement.click(); + }); + }); + }); + + CUSTOM_NO_BUTTONS_CASES.forEach((currentButtonConfig: ButtonsConfig, index: number) => { + it(`shouldn't display anything, because custom config requires a buttons array. Test i=${index}`, () => { + updateInputs(IMAGE_EXTURL, currentButtonConfig); + + // expect a valid ButtonStrategy because passed to this test as input (via currentButtonConfig) + expect(ButtonsStrategy[currentButtonConfig.strategy]).not.toBeUndefined(); + + const element: DebugElement = fixture.debugElement; + const btns: DebugElement[] = element.queryAll(By.css('a.upper-button')); + expect(btns.length).toBe(0); + }); + }); + }); + + describe('---ERROR---', () => { + + NOT_VALID_BTN_TYPE_CASES.forEach((currentButtonConfig: ButtonsConfig, index: number) => { + it(`should throw an error, because all buttons must have valid types. Test i=${index}`, () => { + const ERROR: Error = new Error('Unknown ButtonType. For custom types use ButtonType.CUSTOM'); + expect(() => updateInputs(IMAGE_EXTURL, currentButtonConfig)).toThrow(ERROR); + }); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/upper-buttons/upper-buttons.component.ts b/projects/ks89/angular-modal-gallery/src/lib/components/upper-buttons/upper-buttons.component.ts new file mode 100644 index 00000000..6158c164 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/upper-buttons/upper-buttons.component.ts @@ -0,0 +1,281 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; + +import { AccessibleComponent } from '../accessible.component'; + +import { Action } from '../../model/action.enum'; +import { Image } from '../../model/image.class'; +import { ButtonConfig, ButtonEvent, ButtonsConfig, ButtonsStrategy, ButtonType, WHITELIST_BUTTON_TYPES } from '../../model/buttons-config.interface'; + +import { + KS_DEFAULT_BTN_CLOSE, + KS_DEFAULT_BTN_DELETE, + KS_DEFAULT_BTN_DOWNLOAD, + KS_DEFAULT_BTN_EXTURL, + KS_DEFAULT_BTN_FULL_SCREEN +} from './upper-buttons-default'; + +import { NEXT } from '../../utils/user-input.util'; +import { ConfigService } from '../../services/config.service'; +import { LibConfig } from '../../model/lib-config.interface'; + +/** + * Internal representation of `ButtonConfig` with an optional `id` field, used by trackId to improve performances. + */ +export interface InternalButtonConfig extends ButtonConfig { + id?: number; // useful only for trackById, not needed by users +} + +/** + * Component with all upper buttons. + * Also it emits click events as outputs. + */ +@Component({ + selector: 'ks-upper-buttons', + styleUrls: ['upper-buttons.scss'], + templateUrl: 'upper-buttons.html', + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: false +}) +export class UpperButtonsComponent extends AccessibleComponent implements OnInit { + /** + * Unique id (>=0) of the current instance of this library. This is required when you are using + * the service to call modal gallery. + */ + @Input() + id!: number; + /** + * Object of type `Image` that represent the visible image. + */ + @Input() + currentImage!: Image; + + /** + * Output to emit clicks on refresh button. The payload contains a `ButtonEvent`. + */ + @Output() + refresh: EventEmitter = new EventEmitter(); + /** + * Output to emit clicks on delete button. The payload contains a `ButtonEvent`. + */ + @Output() + delete: EventEmitter = new EventEmitter(); + /** + * Output to emit clicks on navigate button. The payload contains a `ButtonEvent`. + */ + @Output() + navigate: EventEmitter = new EventEmitter(); + /** + * Output to emit clicks on download button. The payload contains a `ButtonEvent`. + */ + @Output() + download: EventEmitter = new EventEmitter(); + /** + * Output to emit clicks on close button. The payload contains a `ButtonEvent`. + */ + @Output() + closeButton: EventEmitter = new EventEmitter(); + /** + * Output to emit clicks on full-screen button. The payload contains a `ButtonEvent`. + */ + @Output() + fullscreen: EventEmitter = new EventEmitter(); + /** + * Output to emit clicks on all custom buttons. The payload contains a `ButtonEvent`. + */ + @Output() + customEmit: EventEmitter = new EventEmitter(); + + /** + * Object of type `ButtonsConfig` to init UpperButtonsComponent's features. + * For instance, it contains an array of buttons. + */ + buttonsConfig: ButtonsConfig | undefined; + /** + * Array of `InternalButtonConfig` exposed to the template. This field is initialized + * applying transformations, default values and so on to the input of the same type. + */ + buttons: InternalButtonConfig[] | undefined; + + /** + * Default buttons array for standard configuration + */ + private defaultButtonsDefault: ButtonConfig[] = [KS_DEFAULT_BTN_CLOSE]; + /** + * Default buttons array for simple configuration + */ + private simpleButtonsDefault: ButtonConfig[] = [KS_DEFAULT_BTN_DOWNLOAD, ...this.defaultButtonsDefault]; + /** + * Default buttons array for advanced configuration + */ + private advancedButtonsDefault: ButtonConfig[] = [KS_DEFAULT_BTN_EXTURL, ...this.simpleButtonsDefault]; + /** + * Default buttons array for full configuration + */ + private fullButtonsDefault: ButtonConfig[] = [ + KS_DEFAULT_BTN_FULL_SCREEN, + KS_DEFAULT_BTN_DELETE, + ...this.advancedButtonsDefault + ]; + + constructor(private configService: ConfigService) { + super(); + } + + /** + * Method ´ngOnInit´ to build `configButtons` applying a default value and also to + * init the `buttons` array. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called only one time!!! + */ + ngOnInit(): void { + const libConfig: LibConfig | undefined = this.configService.getConfig(this.id); + if (!libConfig || !libConfig.buttonsConfig) { + throw new Error('Internal library error - libConfig and buttonsConfig must be defined'); + } + this.buttonsConfig = libConfig.buttonsConfig; + switch (this.buttonsConfig.strategy) { + case ButtonsStrategy.SIMPLE: + this.buttons = this.addButtonIds(this.simpleButtonsDefault); + break; + case ButtonsStrategy.ADVANCED: + this.buttons = this.addButtonIds(this.advancedButtonsDefault); + break; + case ButtonsStrategy.FULL: + this.buttons = this.addButtonIds(this.fullButtonsDefault); + break; + case ButtonsStrategy.CUSTOM: + this.buttons = this.addButtonIds(this.validateCustomButtons(this.buttonsConfig.buttons)); + break; + case ButtonsStrategy.DEFAULT: + default: + this.buttons = this.addButtonIds(this.defaultButtonsDefault); + break; + } + } + + /** + * Method called by events from both keyboard and mouse on a button. + * This will call a private method to trigger an output with the right payload. + * @param InternalButtonConfig button that called this method + * @param KeyboardEvent | MouseEvent event payload + * @param Action action that triggered the source event or `Action.CLICK` if not specified + * @throws an error if the button type is unknown + */ + onEvent(button: InternalButtonConfig, event: KeyboardEvent | MouseEvent, action: Action = Action.CLICK): void { + if (!event) { + return; + } + const dataToEmit: ButtonEvent = { + button, + // current image initialized as null + // (I'll fill this value inside the parent of this component + image: null, + action, + galleryId: this.id + }; + switch (button.type) { + case ButtonType.DELETE: + this.triggerOnMouseAndKeyboard(this.delete, event, dataToEmit); + break; + case ButtonType.EXTURL: + if (!this.currentImage || !this.currentImage.modal || !this.currentImage.modal.extUrl) { + return; + } + this.triggerOnMouseAndKeyboard(this.navigate, event, dataToEmit); + break; + case ButtonType.DOWNLOAD: + this.triggerOnMouseAndKeyboard(this.download, event, dataToEmit); + break; + case ButtonType.CLOSE: + this.triggerOnMouseAndKeyboard(this.closeButton, event, dataToEmit); + break; + case ButtonType.CUSTOM: + this.triggerOnMouseAndKeyboard(this.customEmit, event, dataToEmit); + break; + case ButtonType.FULLSCREEN: + this.triggerOnMouseAndKeyboard(this.fullscreen, event, dataToEmit); + break; + default: + throw new Error(`Unknown button's type into ButtonConfig`); + } + } + + /** + * Method used in the template to track ids in ngFor. + * @param number index of the array + * @param Image item of the array + * @returns number the id of the item or undefined if the item is not valid + */ + trackById(index: number, item: InternalButtonConfig): number | undefined { + return item ? item.id : undefined; + } + + /** + * Private method to emit an event using the specified output as an `EventEmitter`. + * @param EventEmitter emitter is the output to emit the `ButtonEvent` + * @param KeyboardEvent | MouseEvent event is the source that triggered this method + * @param ButtonEvent dataToEmit payload to emit + */ + private triggerOnMouseAndKeyboard(emitter: EventEmitter, event: KeyboardEvent | MouseEvent, dataToEmit: ButtonEvent): void { + if (!emitter) { + throw new Error(`UpperButtonsComponent unknown emitter in triggerOnMouseAndKeyboard`); + } + + const result: number = super.handleImageEvent(event); + if (result === NEXT) { + emitter.emit(dataToEmit); + } + } + + /** + * Private method to add ids to the array of buttons. + * It adds ids in a reverse way, to be sure that the last button will always have id = 0. + * This is really useful in unit testing to be sure that close button always have id = 0, download 1 and so on... + * It's totally transparent to the user. + * @param ButtonConfig[] buttons config array + * @returns ButtonConfig[] the input array with incremental numeric ids + */ + private addButtonIds(buttons: ButtonConfig[]): ButtonConfig[] { + return buttons.map((val: ButtonConfig, i: number) => Object.assign(val, { id: buttons.length - 1 - i })); + } + + /** + * Private method to validate custom buttons received as input. + * @param ButtonConfig[] buttons config array. [] by default. + * @returns ButtonConfig[] the same input buttons config array + * @throws an error is exists a button with an unknown type + */ + private validateCustomButtons(buttons: ButtonConfig[] = []): ButtonConfig[] { + buttons.forEach((val: ButtonConfig) => { + const indexOfButtonType: number = WHITELIST_BUTTON_TYPES.findIndex((type: ButtonType) => type === val.type); + if (indexOfButtonType === -1) { + throw new Error(`Unknown ButtonType. For custom types use ButtonType.CUSTOM`); + } + }); + return buttons; + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/upper-buttons/upper-buttons.html b/projects/ks89/angular-modal-gallery/src/lib/components/upper-buttons/upper-buttons.html new file mode 100644 index 00000000..d89d24a8 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/upper-buttons/upper-buttons.html @@ -0,0 +1,14 @@ +
+ + + + + + +
diff --git a/projects/ks89/angular-modal-gallery/src/lib/components/upper-buttons/upper-buttons.scss b/projects/ks89/angular-modal-gallery/src/lib/components/upper-buttons/upper-buttons.scss new file mode 100644 index 00000000..1d841f94 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/components/upper-buttons/upper-buttons.scss @@ -0,0 +1,117 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// all svgs are converted to base 64 with this website http://b64.io/ + +$upper-btn-margin-right: 30px; +$upper-btn-margin-top: 28px; +$upper-btn-font-size: 50px; +$upper-btn-animation-time: .6s; + +$btn-width: 30px; +$btn-height: 30px; +$btn-bg-size: 30px; +$btn-opacity: .8; +$btn-animation-time: .6s; +$btn-transition-time: .5s; + + +.buttons-container { + display: flex; + flex-direction: row; + justify-content: flex-end; + + > .upper-button { + align-self: center; + margin-right: $upper-btn-margin-right; + margin-top: $upper-btn-margin-top; + font-size: $upper-btn-font-size; + text-decoration: none; + cursor: pointer; + animation: animatezoom $upper-btn-animation-time; + + // Used by custom classes, for instance font-awesome + color: white; + } +} + +@keyframes animatezoom { + from { + transform: scale(0); + } + to { + transform: scale(1); + } +} + +.base-btn { + width: $btn-width; + height: $btn-height; + background-size: $btn-bg-size; + opacity: $btn-opacity; + transition: all $btn-transition-time; + + &:hover { + transform: scale(1.2); + } +} + +.rotate-image { + @extend .base-btn; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDY0IDY0IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA2NCA2NDsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSI1MTJweCIgaGVpZ2h0PSI1MTJweCI+PGc+PGc+PHBhdGggZD0iTTMzLDJjNy43NDYsMCwxNS4wMjgsMy4wMTcsMjAuNTA1LDguNDk0YzEwLjEzOCwxMC4xMzcsMTEuMzEsMjYuMzk2LDIuNzQsMzcuODQ5TDUyLDUyLjU4OVY0NGgtMnYxMWwxLDFoMTF2LTJoLTguNTgyICAgIGw0LjI5Mi00LjI5M2wwLjA5Mi0wLjEwNmM5LjIxMS0xMi4yNDcsNy45NzItMjkuNjY3LTIuODgzLTQwLjUyMUM0OS4wNjQsMy4yMjUsNDEuMjgsMCwzMywwVjJ6IiBmaWxsPSIjRkZGRkZGIi8+PHBhdGggZD0iTTcuNzU1LDE1LjY1N0wxMiwxMS40MTFWMjBoMlY5bC0xLTFIMnYyaDguNTgyTDYuMjksMTQuMjkzbC0wLjA5MiwwLjEwNkMtMy4wMTMsMjYuNjQ2LTEuNzczLDQ0LjA2Niw5LjA4MSw1NC45MiAgICBDMTQuOTM2LDYwLjc3NSwyMi43Miw2NCwzMSw2NHYtMmMtNy43NDYsMC0xNS4wMjgtMy4wMTctMjAuNTA1LTguNDk0QzAuMzU3LDQzLjM2OS0wLjgxNCwyNy4xMSw3Ljc1NSwxNS42NTd6IiBmaWxsPSIjRkZGRkZGIi8+PC9nPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48L3N2Zz4="); +} + +.fullscreen-image { + @extend .base-btn; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNTMgNTMiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUzIDUzOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij48Zz48cGF0aCBkPSJNNTIuOTIzLDAuNjE4Yy0wLjEwMS0wLjI0NC0wLjI5Ni0wLjQzOS0wLjU0MS0wLjU0MUM1Mi4yNiwwLjAyNyw1Mi4xMywwLDUyLDBINDBjLTAuNTUyLDAtMSwwLjQ0OC0xLDFzMC40NDgsMSwxLDFoOS41ODYgICBMMzMuMjkzLDE4LjI5M2MtMC4zOTEsMC4zOTEtMC4zOTEsMS4wMjMsMCwxLjQxNEMzMy40ODgsMTkuOTAyLDMzLjc0NCwyMCwzNCwyMHMwLjUxMi0wLjA5OCwwLjcwNy0wLjI5M0w1MSwzLjQxNFYxMyAgIGMwLDAuNTUyLDAuNDQ4LDEsMSwxczEtMC40NDgsMS0xVjFDNTMsMC44Nyw1Mi45NzMsMC43NCw1Mi45MjMsMC42MTh6IiBmaWxsPSIjRkZGRkZGIi8+PHBhdGggZD0iTTE4LjI5MywzMy4yOTNMMiw0OS41ODZWNDBjMC0wLjU1Mi0wLjQ0OC0xLTEtMXMtMSwwLjQ0OC0xLDF2MTJjMCwwLjEzLDAuMDI3LDAuMjYsMC4wNzcsMC4zODIgICBjMC4xMDEsMC4yNDQsMC4yOTYsMC40MzksMC41NDEsMC41NDFDMC43NCw1Mi45NzMsMC44Nyw1MywxLDUzaDEyYzAuNTUyLDAsMS0wLjQ0OCwxLTFzLTAuNDQ4LTEtMS0xSDMuNDE0bDE2LjI5My0xNi4yOTMgICBjMC4zOTEtMC4zOTEsMC4zOTEtMS4wMjMsMC0xLjQxNFMxOC42ODQsMzIuOTAyLDE4LjI5MywzMy4yOTN6IiBmaWxsPSIjRkZGRkZGIi8+PHBhdGggZD0iTTEsMTRjMC41NTIsMCwxLTAuNDQ4LDEtMVYzLjQxNGwxNi4yOTIsMTYuMjkyYzAuMTk1LDAuMTk1LDAuNDUxLDAuMjkzLDAuNzA3LDAuMjkzczAuNTEyLTAuMDk4LDAuNzA3LTAuMjkzICAgYzAuMzkxLTAuMzkxLDAuMzkxLTEuMDIzLDAtMS40MTRMMy40MTQsMkgxM2MwLjU1MiwwLDEtMC40NDgsMS0xcy0wLjQ0OC0xLTEtMUgxQzAuODcsMCwwLjc0LDAuMDI3LDAuNjE4LDAuMDc3ICAgQzAuMzczLDAuMTc5LDAuMTc5LDAuMzczLDAuMDc3LDAuNjE4QzAuMDI3LDAuNzQsMCwwLjg3LDAsMXYxMkMwLDEzLjU1MiwwLjQ0OCwxNCwxLDE0eiIgZmlsbD0iI0ZGRkZGRiIvPjxwYXRoIGQ9Ik01MiwzOWMtMC41NTIsMC0xLDAuNDQ4LTEsMXY5LjU4NkwzNC43MDcsMzMuMjkyYy0wLjM5MS0wLjM5MS0xLjAyMy0wLjM5MS0xLjQxNCwwcy0wLjM5MSwxLjAyMywwLDEuNDE0TDQ5LjU4Niw1MUg0MCAgIGMtMC41NTIsMC0xLDAuNDQ4LTEsMXMwLjQ0OCwxLDEsMWgxMmMwLjEzLDAsMC4yNi0wLjAyNywwLjM4Mi0wLjA3N2MwLjI0NC0wLjEwMSwwLjQzOS0wLjI5NiwwLjU0MS0wLjU0MSAgIEM1Mi45NzMsNTIuMjYsNTMsNTIuMTMsNTMsNTJWNDBDNTMsMzkuNDQ4LDUyLjU1MiwzOSw1MiwzOXoiIGZpbGw9IiNGRkZGRkYiLz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+"); +} + + +.delete-image { + @extend .base-btn; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ4Ni40IDQ4Ni40IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0ODYuNCA0ODYuNDsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSI1MTJweCIgaGVpZ2h0PSI1MTJweCI+PGc+PGc+PHBhdGggZD0iTTQ0Niw3MEgzNDQuOFY1My41YzAtMjkuNS0yNC01My41LTUzLjUtNTMuNWgtOTYuMmMtMjkuNSwwLTUzLjUsMjQtNTMuNSw1My41VjcwSDQwLjRjLTcuNSwwLTEzLjUsNi0xMy41LDEzLjUgICAgUzMyLjksOTcsNDAuNCw5N2gyNC40djMxNy4yYzAsMzkuOCwzMi40LDcyLjIsNzIuMiw3Mi4yaDIxMi40YzM5LjgsMCw3Mi4yLTMyLjQsNzIuMi03Mi4yVjk3SDQ0NmM3LjUsMCwxMy41LTYsMTMuNS0xMy41ICAgIFM0NTMuNSw3MCw0NDYsNzB6IE0xNjguNiw1My41YzAtMTQuNiwxMS45LTI2LjUsMjYuNS0yNi41aDk2LjJjMTQuNiwwLDI2LjUsMTEuOSwyNi41LDI2LjVWNzBIMTY4LjZWNTMuNXogTTM5NC42LDQxNC4yICAgIGMwLDI0LjktMjAuMyw0NS4yLTQ1LjIsNDUuMkgxMzdjLTI0LjksMC00NS4yLTIwLjMtNDUuMi00NS4yVjk3aDMwMi45djMxNy4ySDM5NC42eiIgZmlsbD0iI0ZGRkZGRiIvPjxwYXRoIGQ9Ik0yNDMuMiw0MTFjNy41LDAsMTMuNS02LDEzLjUtMTMuNVYxNTguOWMwLTcuNS02LTEzLjUtMTMuNS0xMy41cy0xMy41LDYtMTMuNSwxMy41djIzOC41ICAgIEMyMjkuNyw0MDQuOSwyMzUuNyw0MTEsMjQzLjIsNDExeiIgZmlsbD0iI0ZGRkZGRiIvPjxwYXRoIGQ9Ik0xNTUuMSwzOTYuMWM3LjUsMCwxMy41LTYsMTMuNS0xMy41VjE3My43YzAtNy41LTYtMTMuNS0xMy41LTEzLjVzLTEzLjUsNi0xMy41LDEzLjV2MjA4LjkgICAgQzE0MS42LDM5MC4xLDE0Ny43LDM5Ni4xLDE1NS4xLDM5Ni4xeiIgZmlsbD0iI0ZGRkZGRiIvPjxwYXRoIGQ9Ik0zMzEuMywzOTYuMWM3LjUsMCwxMy41LTYsMTMuNS0xMy41VjE3My43YzAtNy41LTYtMTMuNS0xMy41LTEzLjVzLTEzLjUsNi0xMy41LDEzLjV2MjA4LjkgICAgQzMxNy44LDM5MC4xLDMyMy44LDM5Ni4xLDMzMS4zLDM5Ni4xeiIgZmlsbD0iI0ZGRkZGRiIvPjwvZz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+"); +} + +.ext-url-image { + @extend .base-btn; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPjxnPjxnPjxnPjxwYXRoIGQ9Ik00ODAsMjg4djExMmMwLDQ0LjE4My0zNS44MTcsODAtODAsODBIMTEyYy00NC4xODMsMC04MC0zNS44MTctODAtODBWMTEyYzAtNDQuMTgzLDM1LjgxNy04MCw4MC04MGg5NlYwaC05NiAgICAgQzUwLjE0NCwwLDAsNTAuMTQ0LDAsMTEydjI4OGMwLDYxLjg1Niw1MC4xNDQsMTEyLDExMiwxMTJoMjg4YzYxLjg1NiwwLDExMi01MC4xNDQsMTEyLTExMlYyODhINDgweiIgZmlsbD0iI0ZGRkZGRiIvPjxwYXRoIGQ9Ik0xNzYsNDE2aDMyVjI4OGMwLTEyNS43NiwxMDcuNTItMTI4LDExMi0xMjhoMTA1LjQ0bC04NC42NCw4NC42NGwyMi41NiwyMi41NmwxMTItMTEyYzYuMjA0LTYuMjQxLDYuMjA0LTE2LjMxOSwwLTIyLjU2ICAgICBsLTExMi0xMTJsLTIyLjcyLDIyLjcybDg0LjgsODQuNjRIMzIwYy0xLjQ0LDAtMTQ0LDEuNzYtMTQ0LDE2MFY0MTZ6IiBmaWxsPSIjRkZGRkZGIi8+PC9nPjwvZz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+"); +} + +.download-image { + @extend .base-btn; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ3MS4yIDQ3MS4yIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0NzEuMiA0NzEuMjsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSI1MTJweCIgaGVpZ2h0PSI1MTJweCI+PGc+PGc+PHBhdGggZD0iTTQ1Ny43LDIzMC4xNWMtNy41LDAtMTMuNSw2LTEzLjUsMTMuNXYxMjIuOGMwLDMzLjQtMjcuMiw2MC41LTYwLjUsNjAuNUg4Ny41Yy0zMy40LDAtNjAuNS0yNy4yLTYwLjUtNjAuNXYtMTI0LjggICAgYzAtNy41LTYtMTMuNS0xMy41LTEzLjVzLTEzLjUsNi0xMy41LDEzLjV2MTI0LjhjMCw0OC4zLDM5LjMsODcuNSw4Ny41LDg3LjVoMjk2LjJjNDguMywwLDg3LjUtMzkuMyw4Ny41LTg3LjV2LTEyMi44ICAgIEM0NzEuMiwyMzYuMjUsNDY1LjIsMjMwLjE1LDQ1Ny43LDIzMC4xNXoiIGZpbGw9IiNGRkZGRkYiLz48cGF0aCBkPSJNMjI2LjEsMzQ2Ljc1YzIuNiwyLjYsNi4xLDQsOS41LDRzNi45LTEuMyw5LjUtNGw4NS44LTg1LjhjNS4zLTUuMyw1LjMtMTMuOCwwLTE5LjFjLTUuMy01LjMtMTMuOC01LjMtMTkuMSwwbC02Mi43LDYyLjggICAgVjMwLjc1YzAtNy41LTYtMTMuNS0xMy41LTEzLjVzLTEzLjUsNi0xMy41LDEzLjV2MjczLjlsLTYyLjgtNjIuOGMtNS4zLTUuMy0xMy44LTUuMy0xOS4xLDBjLTUuMyw1LjMtNS4zLDEzLjgsMCwxOS4xICAgIEwyMjYuMSwzNDYuNzV6IiBmaWxsPSIjRkZGRkZGIi8+PC9nPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48L3N2Zz4="); +} + +.close-image { + @extend .base-btn; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ3NS4yIDQ3NS4yIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0NzUuMiA0NzUuMjsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSI1MTJweCIgaGVpZ2h0PSI1MTJweCI+PGc+PGc+PHBhdGggZD0iTTQwNS42LDY5LjZDMzYwLjcsMjQuNywzMDEuMSwwLDIzNy42LDBzLTEyMy4xLDI0LjctMTY4LDY5LjZTMCwxNzQuMSwwLDIzNy42czI0LjcsMTIzLjEsNjkuNiwxNjhzMTA0LjUsNjkuNiwxNjgsNjkuNiAgICBzMTIzLjEtMjQuNywxNjgtNjkuNnM2OS42LTEwNC41LDY5LjYtMTY4UzQ1MC41LDExNC41LDQwNS42LDY5LjZ6IE0zODYuNSwzODYuNWMtMzkuOCwzOS44LTkyLjcsNjEuNy0xNDguOSw2MS43ICAgIHMtMTA5LjEtMjEuOS0xNDguOS02MS43Yy04Mi4xLTgyLjEtODIuMS0yMTUuNywwLTI5Ny44QzEyOC41LDQ4LjksMTgxLjQsMjcsMjM3LjYsMjdzMTA5LjEsMjEuOSwxNDguOSw2MS43ICAgIEM0NjguNiwxNzAuOCw0NjguNiwzMDQuNCwzODYuNSwzODYuNXoiIGZpbGw9IiNGRkZGRkYiLz48cGF0aCBkPSJNMzQyLjMsMTMyLjljLTUuMy01LjMtMTMuOC01LjMtMTkuMSwwbC04NS42LDg1LjZMMTUyLDEzMi45Yy01LjMtNS4zLTEzLjgtNS4zLTE5LjEsMGMtNS4zLDUuMy01LjMsMTMuOCwwLDE5LjEgICAgbDg1LjYsODUuNmwtODUuNiw4NS42Yy01LjMsNS4zLTUuMywxMy44LDAsMTkuMWMyLjYsMi42LDYuMSw0LDkuNSw0czYuOS0xLjMsOS41LTRsODUuNi04NS42bDg1LjYsODUuNmMyLjYsMi42LDYuMSw0LDkuNSw0ICAgIGMzLjUsMCw2LjktMS4zLDkuNS00YzUuMy01LjMsNS4zLTEzLjgsMC0xOS4xbC04NS40LTg1LjZsODUuNi04NS42QzM0Ny42LDE0Ni43LDM0Ny42LDEzOC4yLDM0Mi4zLDEzMi45eiIgZmlsbD0iI0ZGRkZGRiIvPjwvZz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+"); +} + +.refresh-image { + @extend .base-btn; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ4OS43MTEgNDg5LjcxMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDg5LjcxMSA0ODkuNzExOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij48Zz48Zz48cGF0aCBkPSJNMTEyLjE1Niw5Ny4xMTFjNzIuMy02NS40LDE4MC41LTY2LjQsMjUzLjgtNi43bC01OC4xLDIuMmMtNy41LDAuMy0xMy4zLDYuNS0xMywxNGMwLjMsNy4zLDYuMywxMywxMy41LDEzICAgIGMwLjIsMCwwLjMsMCwwLjUsMGw4OS4yLTMuM2M3LjMtMC4zLDEzLTYuMiwxMy0xMy41di0xYzAtMC4yLDAtMC4zLDAtMC41di0wLjFsMCwwbC0zLjMtODguMmMtMC4zLTcuNS02LjYtMTMuMy0xNC0xMyAgICBjLTcuNSwwLjMtMTMuMyw2LjUtMTMsMTRsMi4xLDU1LjNjLTM2LjMtMjkuNy04MS00Ni45LTEyOC44LTQ5LjNjLTU5LjItMy0xMTYuMSwxNy4zLTE2MCw1Ny4xYy02MC40LDU0LjctODYsMTM3LjktNjYuOCwyMTcuMSAgICBjMS41LDYuMiw3LDEwLjMsMTMuMSwxMC4zYzEuMSwwLDIuMS0wLjEsMy4yLTAuNGM3LjItMS44LDExLjctOS4xLDkuOS0xNi4zQzM2LjY1NiwyMTguMjExLDU5LjA1NiwxNDUuMTExLDExMi4xNTYsOTcuMTExeiIgZmlsbD0iI0ZGRkZGRiIvPjxwYXRoIGQ9Ik00NjIuNDU2LDE5NS41MTFjLTEuOC03LjItOS4xLTExLjctMTYuMy05LjljLTcuMiwxLjgtMTEuNyw5LjEtOS45LDE2LjNjMTYuOSw2OS42LTUuNiwxNDIuNy01OC43LDE5MC43ICAgIGMtMzcuMywzMy43LTg0LjEsNTAuMy0xMzAuNyw1MC4zYy00NC41LDAtODguOS0xNS4xLTEyNC43LTQ0LjlsNTguOC01LjNjNy40LTAuNywxMi45LTcuMiwxMi4yLTE0LjdzLTcuMi0xMi45LTE0LjctMTIuMmwtODguOSw4ICAgIGMtNy40LDAuNy0xMi45LDcuMi0xMi4yLDE0LjdsOCw4OC45YzAuNiw3LDYuNSwxMi4zLDEzLjQsMTIuM2MwLjQsMCwwLjgsMCwxLjItMC4xYzcuNC0wLjcsMTIuOS03LjIsMTIuMi0xNC43bC00LjgtNTQuMSAgICBjMzYuMywyOS40LDgwLjgsNDYuNSwxMjguMyw0OC45YzMuOCwwLjIsNy42LDAuMywxMS4zLDAuM2M1NS4xLDAsMTA3LjUtMjAuMiwxNDguNy01Ny40ICAgIEM0NTYuMDU2LDM1Ny45MTEsNDgxLjY1NiwyNzQuODExLDQ2Mi40NTYsMTk1LjUxMXoiIGZpbGw9IiNGRkZGRkYiLz48L2c+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjwvc3ZnPg=="); +} + +.copy { + @extend .base-btn; + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ4OC4zIDQ4OC4zIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0ODguMyA0ODguMzsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSI1MTJweCIgaGVpZ2h0PSI1MTJweCI+PGc+PGc+PHBhdGggZD0iTTMxNC4yNSw4NS40aC0yMjdjLTIxLjMsMC0zOC42LDE3LjMtMzguNiwzOC42djMyNS43YzAsMjEuMywxNy4zLDM4LjYsMzguNiwzOC42aDIyN2MyMS4zLDAsMzguNi0xNy4zLDM4LjYtMzguNlYxMjQgICAgQzM1Mi43NSwxMDIuNywzMzUuNDUsODUuNCwzMTQuMjUsODUuNHogTTMyNS43NSw0NDkuNmMwLDYuNC01LjIsMTEuNi0xMS42LDExLjZoLTIyN2MtNi40LDAtMTEuNi01LjItMTEuNi0xMS42VjEyNCAgICBjMC02LjQsNS4yLTExLjYsMTEuNi0xMS42aDIyN2M2LjQsMCwxMS42LDUuMiwxMS42LDExLjZWNDQ5LjZ6IiBmaWxsPSIjRkZGRkZGIi8+PHBhdGggZD0iTTQwMS4wNSwwaC0yMjdjLTIxLjMsMC0zOC42LDE3LjMtMzguNiwzOC42YzAsNy41LDYsMTMuNSwxMy41LDEzLjVzMTMuNS02LDEzLjUtMTMuNWMwLTYuNCw1LjItMTEuNiwxMS42LTExLjZoMjI3ICAgIGM2LjQsMCwxMS42LDUuMiwxMS42LDExLjZ2MzI1LjdjMCw2LjQtNS4yLDExLjYtMTEuNiwxMS42Yy03LjUsMC0xMy41LDYtMTMuNSwxMy41czYsMTMuNSwxMy41LDEzLjVjMjEuMywwLDM4LjYtMTcuMywzOC42LTM4LjYgICAgVjM4LjZDNDM5LjY1LDE3LjMsNDIyLjM1LDAsNDAxLjA1LDB6IiBmaWxsPSIjRkZGRkZGIi8+PC9nPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48L3N2Zz4="); +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/a-tag-bg-image.directive.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/a-tag-bg-image.directive.spec.ts new file mode 100644 index 00000000..eaf6bb93 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/a-tag-bg-image.directive.spec.ts @@ -0,0 +1,237 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component, DebugElement } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By, SafeResourceUrl } from '@angular/platform-browser'; +import { ATagBgImageDirective } from './a-tag-bg-image.directive'; +import { Image, PlainImage } from '../model/image.class'; + +interface TestModel { + image: Image; + style: string; +} + +const base64: SafeResourceUrl = 'data:image/png;base64,iVBORw0KG='; + +const expectedModal: TestModel[] = [ + {image: new Image(0, {img: 'path'}), style: '50% 50% / cover'}, + {image: new Image(0, {img: 'path'}), style: ''} +]; + +const expectedPlain: TestModel[] = [ + {image: new Image(1, {img: 'path'}, {img: 'plainPath'}), style: '50% 50% / cover'}, + {image: new Image(1, {img: 'path'}, {img: 'plainPath'}), style: ''} +]; + +const expectedModalBase64: TestModel[] = [ + {image: new Image(0, {img: base64 as SafeResourceUrl}), style: '50% 50% / cover'}, + {image: new Image(0, {img: base64 as SafeResourceUrl}), style: ''} +]; + +const expectedPlainBase64: TestModel[] = [ + {image: new Image(1, {img: base64 as SafeResourceUrl}, {img: base64 as SafeResourceUrl}), style: '50% 50% / cover'}, + {image: new Image(1, {img: base64 as SafeResourceUrl}, {img: base64 as SafeResourceUrl}), style: ''} +]; + +const expectedWrongPlain: TestModel[] = [ + // @ts-ignore + {image: new Image(2, {img: 'path'}, {img: null}), style: '50% 50% / cover'}, + // @ts-ignore + {image: new Image(3, {img: 'path'}, {img: undefined}), style: '50% 50% / cover'} +]; + +const expectedWithNoImages: TestModel[] = [ + // @ts-ignore + {image: null, style: '50% 50% / cover'}, + // @ts-ignore + {image: null, style: ''}, + // @ts-ignore + {image: undefined, style: '50% 50% / cover'}, + // @ts-ignore + {image: undefined, style: ''} +]; + +const expectedPlainWithFallback: TestModel[] = [ + {image: new Image(1, {img: 'path'}, {img: 'plainPath', fallbackImg: 'fallbackmodal.jpg'}), style: '50% 50% / cover'} +]; + +const length: number = expectedModal.length + expectedPlain.length + expectedWrongPlain.length + + expectedWithNoImages.length + expectedModalBase64.length + expectedPlainBase64.length + + expectedPlainWithFallback.length; + +@Component({ + selector: 'ks-test-atagbgimage', + template: ` +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+ + +
+ `, + standalone: false +}) +class TestATagBgImageComponent { + base64: SafeResourceUrl = 'data:image/png;base64,iVBORw0KG='; + + images: Image[] = [ + new Image(0, {img: 'path'}), + // @ts-ignore + new Image(1, {img: 'path'}, {img: 'plainPath'}), + // @ts-ignore + new Image(2, {img: 'path'}, {img: null}), + // @ts-ignore + new Image(3, {img: 'path'}, {img: undefined}), + new Image(4, {img: this.base64}), + new Image(5, {img: this.base64}, {img: this.base64}) + ]; + + expectedPlainWithFallback: Image[] = [ + new Image(1, {img: 'path'}, {img: 'plainPath', fallbackImg: 'fallbackmodal.jpg'}) + ]; +} + +let fixture: ComponentFixture; +let comp: TestATagBgImageComponent; +let des: DebugElement[] = []; +let bareElement: DebugElement; + +describe('ATagBgImageDirective', () => { + + beforeEach(() => { + TestBed.resetTestingModule(); + TestBed.configureTestingModule({ + declarations: [TestATagBgImageComponent, ATagBgImageDirective] + }); // not necessary with webpack .compileComponents(); + fixture = TestBed.createComponent(TestATagBgImageComponent); + comp = fixture.componentInstance; + + fixture.detectChanges(); + return fixture.whenStable().then(() => { + fixture.detectChanges(); + bareElement = fixture.debugElement.query(By.css('div:not(ksATagBgImage)')); + des = fixture.debugElement.queryAll(By.directive(ATagBgImageDirective)); + }); + }); + + it('can instantiate it', () => expect(comp).not.toBeNull()); + + describe('---tests---', () => { + + beforeEach(() => fixture.detectChanges()); + + it('should have this directive', () => { + expect(des.length).toBe(length); + }); + + // Different browsers manage this scenario in different ways, + // for instance, some of them apply default stuff like 'repeat scroll 0% 0%', + // others prepend 'localhost:port' to the path. + // So, I decided to use 'toContain', ignoring all other stuff. + + expectedModal.forEach((val: TestModel, index: number) => { + it(`should check expected results for
with an Image (only modal) at position ${index}`, () => { + // no plain image, only modal + const path: string | SafeResourceUrl = val.image.modal.img; + const style: string = val.style; + expect(des[index].nativeElement.style.background).toContain(`url("${path}")`.trim()); + expect(des[index].nativeElement.style.background).toContain(`${style}`.trim()); + }); + }); + + expectedPlain.forEach((val: TestModel, index: number) => { + it(`should check expected results for
with an Image (modal + plain) at position ${index}`, () => { + // when there are both modal and plain, plain wins + const path: string | SafeResourceUrl = (val.image.plain as PlainImage).img; + const style: string = val.style; + const prevIndex: number = expectedModal.length; + expect(des[index + prevIndex].nativeElement.style.background).toContain(`url("${path}")`.trim()); + expect(des[index + prevIndex].nativeElement.style.background).toContain(`${style}`.trim()); + }); + }); + + it(`should check expected results for
with an Image (only modal) as base66`, () => { + // no plain image, only modal + // const base64String: string = expectedModalBase64[0].modal.img; + // const path: SafeResourceUrl = base64String; + // const style: string = expectedModalBase64[0].style; + expect(des[10].nativeElement.style.background).toContain(`url("${expectedModalBase64[0].image.modal.img as string}")`.trim()); + expect(des[10].nativeElement.style.background).toContain(`${expectedModalBase64[0].style}`.trim()); + expect(des[11].nativeElement.style.background).toContain(`url("${expectedModalBase64[1].image.modal.img as string}")`.trim()); + expect(des[11].nativeElement.style.background).toContain(`${expectedModalBase64[1].style}`.trim()); + }); + + it(`should check expected results for
with an Image (modal + plain) as base64`, () => { + // when there are both modal and plain, plain wins + expect(des[12].nativeElement.style.background).toContain(`url("${(expectedPlainBase64[0].image.plain as PlainImage).img as string}")`.trim()); + expect(des[12].nativeElement.style.background).toContain(`${expectedPlainBase64[0].style}`.trim()); + expect(des[13].nativeElement.style.background).toContain(`url("${(expectedPlainBase64[1].image.plain as PlainImage).img as string}")`.trim()); + expect(des[13].nativeElement.style.background).toContain(`${expectedPlainBase64[1].style}`.trim()); + }); + + expectedWrongPlain.forEach((val: TestModel, index: number) => { + it(`should check expected results for
with an Image (modal + plain without img) at position ${index}`, () => { + // plain malformed without an img, so modal wins + const base64String: string = (val.image.plain as PlainImage).img as string; + const path: string | SafeResourceUrl = val.image.modal.img; + const style: string = val.style; + const prevIndex: number = +expectedModal.length + expectedPlain.length; + expect(des[index + prevIndex].nativeElement.style.background).toContain(`url("${path}")`.trim()); + expect(des[index + prevIndex].nativeElement.style.background).toContain(`${style}`.trim()); + }); + }); + + expectedWithNoImages.forEach((val: TestModel, index: number) => { + it(`should check expected results for
when input Image is not valid at position ${index}`, () => { + // no input image + const style: string = val.style; + const prevIndex: number = +expectedModal.length + expectedPlain.length + expectedWrongPlain.length; + expect(des[index + prevIndex].nativeElement.style.background).toBe(''); + }); + }); + + expectedPlainWithFallback.forEach((val: TestModel, index: number) => { + it(`should check expected results for
when plain image has a fallback image ${index}`, () => { + expect(des[index].nativeElement.style.background).toContain(`url("${'path'}")`.trim()); + }); + }); + + it('should check expected results for bare
without this directive', () => { + expect(bareElement.properties.ksATagBgImage).toBeUndefined(); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/a-tag-bg-image.directive.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/a-tag-bg-image.directive.ts new file mode 100644 index 00000000..d3e71ef7 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/a-tag-bg-image.directive.ts @@ -0,0 +1,89 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Directive, ElementRef, Input, OnChanges, OnInit, Renderer2 } from '@angular/core'; + +import { Image } from '../model/image.class'; +import { SafeResourceUrl } from '@angular/platform-browser'; + +/** + * Directive to add an image to an `` tag with some additional custom properties. + */ +@Directive({ + selector: '[ksATagBgImage]', + standalone: false +}) +export class ATagBgImageDirective implements OnInit, OnChanges { + /** + * Object of type `Image` that represents the image to add to the `` tag. + */ + @Input() + image: Image | undefined; + /** + * Additional style to customize the background attribute. + * Empty string by default. + */ + @Input() + style: string | undefined; + + constructor(private renderer: Renderer2, private el: ElementRef) {} + + /** + * Method ´ngOnInit´ to apply the style of this directive. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called only one time!!! + */ + ngOnInit(): void { + this.applyStyle(); + } + + /** + * Method ´ngOnChanges´ to apply the style of this directive. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called when any data-bound property of a directive changes!!! + */ + ngOnChanges(): void { + this.applyStyle(); + } + + /** + * Private method to add an image as background of an `` tag. + */ + private applyStyle(): void { + if (!this.image || (!this.image.plain && !this.image.modal)) { + return; + } + + const imgPath: string | SafeResourceUrl = this.image.plain && this.image.plain.img ? this.image.plain.img : this.image.modal.img; + let bg = `url("${imgPath}") ${this.style}`; + + const fallbackImgPath: string | SafeResourceUrl | undefined = + this.image.plain && this.image.plain.fallbackImg ? this.image.plain.fallbackImg : this.image.modal.fallbackImg; + if (!!fallbackImgPath) { + bg += `, url("${fallbackImgPath}") ${this.style}`; + } + + this.renderer.setStyle(this.el.nativeElement, 'background', bg); + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/click-outside.directive.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/click-outside.directive.spec.ts new file mode 100644 index 00000000..c29e289f --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/click-outside.directive.spec.ts @@ -0,0 +1,140 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component, DebugElement, EventEmitter, Output } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ClickOutsideDirective } from './click-outside.directive'; +import { By } from '@angular/platform-browser'; + +@Component({ + selector: 'ks-test-click-outside', + template: ` + + `, + standalone: false +}) +class TestClickOutsideComponent { + @Output() clicked: EventEmitter = new EventEmitter(); + + onClickOutside(event: boolean): void { + this.clicked.emit(event); + } +} + +let fixture: ComponentFixture; +let comp: TestClickOutsideComponent; +let des: DebugElement[] = []; +let directive: ClickOutsideDirective; + +describe('ClickOutsideDirective', () => { + beforeEach(() => { + TestBed.resetTestingModule(); + TestBed.configureTestingModule({ + declarations: [TestClickOutsideComponent, ClickOutsideDirective] + }); // not necessary with webpack .compileComponents(); + + fixture = TestBed.createComponent(TestClickOutsideComponent); + comp = fixture.componentInstance; + + fixture.detectChanges(); + return fixture.whenStable().then(() => { + fixture.detectChanges(); + des = fixture.debugElement.queryAll(By.directive(ClickOutsideDirective)); + directive = des[0].injector.get(ClickOutsideDirective) as ClickOutsideDirective; + }); + }); + + it('can instantiate it', () => expect(comp).not.toBeNull()); + + it('should have click-outside directive', () => { + expect(des.length).toBe(1); + }); + + describe('---click outside---', () => { + beforeEach(() => fixture.detectChanges()); + + it(`should check for ksClickOutside`, () => { + const clickOutsideDirective: DebugElement = fixture.debugElement.query(By.directive(ClickOutsideDirective)); + expect(clickOutsideDirective.name).toBe('div'); + expect(clickOutsideDirective.attributes.id).toBe('modal-gallery-wrapper'); + expect(clickOutsideDirective.attributes.ksClickOutside).toBe(''); + }); + + it(`should close the modal gallery after a click`, () => { + directive.clickOutsideEnable = true; + fixture.detectChanges(); + const overlay: DebugElement = fixture.debugElement.query(By.css('div#modal-gallery-wrapper')); + comp.clicked.subscribe((res: boolean) => { + expect(res).toBe(true); + }); + // in this scenario I'm using the native click + overlay.nativeElement.click(); + }); + + it(`shouldn't close the modal gallery after a click, because close-outside directive is disabled`, () => { + directive.clickOutsideEnable = false; + fixture.detectChanges(); + const overlay: DebugElement = fixture.debugElement.query(By.css('div#modal-gallery-wrapper')); + comp.clicked.subscribe(() => { + fail('if clickOutsideEnable = false there will be no clicked events'); + }); + overlay.nativeElement.click(); + }); + + it(`shouldn't close the modal gallery after a click over the current-image, because it isn't 'inside'`, () => { + directive.clickOutsideEnable = true; + fixture.detectChanges(); + const image: DebugElement = fixture.debugElement.query(By.css('img#current-image-test')); + comp.clicked.subscribe((res: boolean) => { + fail(`if it's 'not inside' (variable isInside = false) there will be no clicked events`); + }); + image.nativeElement.click(); + }); + + it(`should close the modal gallery after a click over an 'hidden' div`, () => { + directive.clickOutsideEnable = true; + fixture.detectChanges(); + const image: DebugElement = fixture.debugElement.query(By.css('div#hidden-div-test')); + comp.clicked.subscribe((res: boolean) => { + expect(res).toBe(true); + }); + image.nativeElement.click(); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/click-outside.directive.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/click-outside.directive.ts new file mode 100644 index 00000000..9770ee78 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/click-outside.directive.ts @@ -0,0 +1,90 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Directive, EventEmitter, HostListener, Input, Output } from '@angular/core'; + +/** + * Directive to close the modal gallery clicking on the semi-transparent background. + * In fact, it listens for a click on all elements that aren't 'inside' and it emits + * an event using `@Output clickOutside`. + */ +@Directive({ + selector: '[ksClickOutside]', + standalone: false +}) +export class ClickOutsideDirective { + /** + * Boolean to enable this directive. + */ + @Input() + clickOutsideEnable: boolean | undefined; + /** + * Output to emit an event if the clicked element class doesn't contain 'inside' or it is 'hidden'. The payload is a boolean. + */ + @Output() + clickOutside: EventEmitter = new EventEmitter(); + + /** + * Method called by Angular itself every click thanks to `@HostListener`. + * @param event MouseEvent + */ + @HostListener('click', ['$event']) + onClick(event: MouseEvent): void { + event.stopPropagation(); + + // tslint:disable-next-line:no-any + const target: any = event.target; + + if (!this.clickOutsideEnable || !target) { + return; + } + + let isInside = false; + let isHidden = false; + + if (typeof target.className !== 'string') { + // it happens with @fortawesome/fontawesome 5 + // for some reasons className is an object with 2 empty properties inside + isInside = true; + } else { + // in normal scenarios, use classname, because it's a simple string + isInside = target.className && target.className.includes('inside'); + isHidden = target.className.includes('hidden'); + } + + // if inside => don't close modal gallery + // if hidden => close modal gallery + /* + i i' h | close + 0 1 0 | 1 => close modal gallery + 0 1 1 | 1 => close modal gallery + 1 0 0 | 0 + 1 0 1 | 1 => close modal gallery + */ + if (!isInside || isHidden) { + // close modal gallery + this.clickOutside.emit(true); + } + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/description.directive.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/description.directive.spec.ts new file mode 100644 index 00000000..f36a4a62 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/description.directive.spec.ts @@ -0,0 +1,183 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component, DebugElement } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DescriptionDirective } from './description.directive'; +import { Description, DescriptionStrategy } from '../model/description.interface'; +import { ComponentFixtureAutoDetect } from '@angular/core/testing'; + +const expected: Description[] | undefined[] = [ + { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + style: {bgColor: 'rgba(0, 0, 0, 0.5)', textColor: 'white', marginTop: '0px', marginBottom: '5px', marginLeft: '0px', marginRight: '0px'} + }, + { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + style: {marginTop: '0px', marginBottom: '5px', marginLeft: '0px', marginRight: '0px'} + }, + { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + style: {bgColor: 'rgba(0, 0, 0, 0.5)', textColor: 'white'} + }, + { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + style: {bgColor: 'rgba(255, 0, 0, .5)', marginBottom: '0px'} + }, + { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + style: {height: '30px', width: '100px', position: 'absolute', top: '0px', bottom: '0px', left: '0px', right: '0px'} + }, + { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + style: {bgColor: 'rgba(0, 0, 0, 0.5)', textColor: 'white'} + }, + {strategy: DescriptionStrategy.ALWAYS_VISIBLE, style: {}}, + {strategy: DescriptionStrategy.ALWAYS_VISIBLE} +]; + +@Component({ + selector: 'ks-test-description', + template: ` +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `, + standalone: false +}) +class TestDescriptionComponent { + descriptions: Description[] | undefined[] = [ + { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + style: {bgColor: 'rgba(0, 0, 0, 0.5)', textColor: 'white', marginTop: '0px', marginBottom: '5px', marginLeft: '0px', marginRight: '0px'} + }, + { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + style: {marginTop: '0px', marginBottom: '5px', marginLeft: '0px', marginRight: '0px'} + }, + { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + style: {bgColor: 'rgba(0, 0, 0, 0.5)', textColor: 'white'} + }, + { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + style: {bgColor: 'rgba(255, 0, 0, .5)', marginBottom: '0px'} + }, + { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + style: {height: '30px', width: '100px', position: 'absolute', top: '0px', bottom: '0px', left: '0px', right: '0px'} + }, + { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + style: {bgColor: 'rgba(0, 0, 0, 0.5)', textColor: 'white'} + }, + {strategy: DescriptionStrategy.ALWAYS_VISIBLE, style: {}}, + {strategy: DescriptionStrategy.ALWAYS_VISIBLE} + ]; +} + +let fixture: ComponentFixture; +let comp: TestDescriptionComponent; +let des: DebugElement[] = []; +let bareElement: DebugElement; + +describe('DescriptionDirective', () => { + + beforeEach(async () => { + TestBed.resetTestingModule(); + await TestBed.configureTestingModule({ + declarations: [TestDescriptionComponent, DescriptionDirective], + providers: [ + {provide: ComponentFixtureAutoDetect, useValue: true} + ] + }).compileComponents(); + fixture = TestBed.createComponent(TestDescriptionComponent); + comp = fixture.componentInstance; + fixture.detectChanges(); // initial binding + + await fixture.whenStable(); + + fixture.detectChanges(); + bareElement = fixture.debugElement.query(By.css('figcaption:not(ksDescription)')); + des = fixture.debugElement.queryAll(By.directive(DescriptionDirective)); + }); + + it('can instantiate it', () => expect(comp).not.toBeNull()); + + describe('---tests---', () => { + + beforeEach(() => fixture.detectChanges()); + + it('should have this directive', () => { + expect(des.length).toBe(expected.length); + }); + + expected.forEach((val: Description, index: number) => { + it(`should check expected results for
at position ${index}`, () => { + if (val && val.style && val.style.bgColor && val.style.textColor) { + expect(des[index].styles.background).toBe(val.style.bgColor); + expect(des[index].styles.color).toBe(val.style.textColor); + + expect(des[index].nativeElement.style.position).toBe(val.style.position ? val.style.position : ''); + expect(des[index].nativeElement.style.top).toBe(val.style.top ? val.style.top : ''); + expect(des[index].nativeElement.style.bottom).toBe(val.style.bottom ? val.style.bottom : ''); + expect(des[index].nativeElement.style.left).toBe(val.style.left ? val.style.left : ''); + expect(des[index].nativeElement.style.right).toBe(val.style.right ? val.style.right : ''); + expect(des[index].nativeElement.style.width).toBe(val.style.width ? val.style.width : ''); + expect(des[index].nativeElement.style.height).toBe(val.style.height ? val.style.height : ''); + expect(des[index].nativeElement.style.marginTop).toBe(val.style.marginTop ? val.style.marginTop : '0px'); + expect(des[index].nativeElement.style.marginBottom).toBe(val.style.marginBottom ? val.style.marginBottom : '0px'); + expect(des[index].nativeElement.style.marginLeft).toBe(val.style.marginLeft ? val.style.marginLeft : '0px'); + expect(des[index].nativeElement.style.marginRight).toBe(val.style.marginRight ? val.style.marginRight : '0px'); + } + }); + }); + + it('should check expected results for bare
without this directive', () => { + expect(bareElement.properties.ksDescription).toBeUndefined(); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/description.directive.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/description.directive.ts new file mode 100644 index 00000000..bbc77a5d --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/description.directive.ts @@ -0,0 +1,102 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Directive, ElementRef, Input, OnChanges, OnInit, Renderer2 } from '@angular/core'; +import { Description } from '../model/description.interface'; + +/** + * Directive to customize the description. + */ +@Directive({ + selector: '[ksDescription]', + standalone: false +}) +export class DescriptionDirective implements OnInit, OnChanges { + /** + * Object of type `Description` to resize the element. + */ + @Input() + description: Description | undefined; + + constructor(private renderer: Renderer2, private el: ElementRef) {} + + /** + * Method ´ngOnInit´ to apply the style of this directive. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called only one time!!! + */ + ngOnInit(): void { + this.applyStyle(); + } + + /** + * Method ´ngOnChanges´ to apply the style of this directive. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called when any data-bound property of a directive changes!!! + */ + ngOnChanges(): void { + this.applyStyle(); + } + + /** + * Private method to change description's style. + */ + private applyStyle(): void { + if (!this.description) { + return; + } + + if (this.description.style) { + this.renderer.setStyle(this.el.nativeElement, 'background', this.description.style.bgColor); + this.renderer.setStyle(this.el.nativeElement, 'color', this.description.style.textColor); + + if (this.description.style.width) { + this.renderer.setStyle(this.el.nativeElement, 'width', this.description.style.width); + } + if (this.description.style.height) { + this.renderer.setStyle(this.el.nativeElement, 'height', this.description.style.height); + } + if (this.description.style.position) { + this.renderer.setStyle(this.el.nativeElement, 'position', this.description.style.position); + } + if (this.description.style.top) { + this.renderer.setStyle(this.el.nativeElement, 'top', this.description.style.top); + } + if (this.description.style.bottom) { + this.renderer.setStyle(this.el.nativeElement, 'bottom', this.description.style.bottom); + } + if (this.description.style.left) { + this.renderer.setStyle(this.el.nativeElement, 'left', this.description.style.left); + } + if (this.description.style.right) { + this.renderer.setStyle(this.el.nativeElement, 'right', this.description.style.right); + } + + this.renderer.setStyle(this.el.nativeElement, 'margin-top', this.description.style.marginTop ? this.description.style.marginTop : '0px'); + this.renderer.setStyle(this.el.nativeElement, 'margin-bottom', this.description.style.marginBottom ? this.description.style.marginBottom : '0px'); + this.renderer.setStyle(this.el.nativeElement, 'margin-left', this.description.style.marginLeft ? this.description.style.marginLeft : '0px'); + this.renderer.setStyle(this.el.nativeElement, 'margin-right', this.description.style.marginRight ? this.description.style.marginRight : '0px'); + } + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/direction.directive.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/direction.directive.spec.ts new file mode 100644 index 00000000..9d1d24e7 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/direction.directive.spec.ts @@ -0,0 +1,110 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component, DebugElement } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DirectionDirective } from './direction.directive'; + +interface TestModel { + direction: string; + justify: string; +} + +const expected: TestModel[] = [ + // direction can be: row | row-reverse | column | column-reverse + // justify can be: flex-start | flex-end | center | space-between | space-around | space-evenly + {direction: 'row', justify: 'flex-start'}, + {direction: 'row-reverse', justify: 'flex-end'}, + {direction: 'column', justify: 'center'}, + {direction: 'column-reverse', justify: 'space-between'}, + {direction: 'row', justify: 'space-around'}, + {direction: 'row', justify: 'space-evenly'}, + {direction: '', justify: ''}, // with '' and '' the expected result is '' and '' + {direction: '', justify: ''}, // with '' and 'center' the expected result is '' and '' + {direction: '', justify: ''} // with 'row' and '' the expected result is '' and '' +]; + +@Component({ + selector: 'ks-test-direction', + template: ` +
+
+
+
+
+
+
+
+
+ `, + standalone: false +}) +class TestDirectionComponent {} + +let fixture: ComponentFixture; +let comp: TestDirectionComponent; +let des: DebugElement[] = []; +let bareElement: DebugElement; + +describe('DirectionDirective', () => { + + beforeEach(() => { + TestBed.resetTestingModule(); + TestBed.configureTestingModule({ + declarations: [TestDirectionComponent, DirectionDirective] + }); // not necessary with webpack .compileComponents(); + fixture = TestBed.createComponent(TestDirectionComponent); + comp = fixture.componentInstance; + + fixture.detectChanges(); + return fixture.whenStable().then(() => { + fixture.detectChanges(); + bareElement = fixture.debugElement.query(By.css('div:not(ksDirection)')); + des = fixture.debugElement.queryAll(By.directive(DirectionDirective)); + }); + }); + + it('can instantiate it', () => expect(comp).not.toBeNull()); + + describe('---tests---', () => { + + beforeEach(() => fixture.detectChanges()); + + it('should have this directive', () => { + expect(des.length).toBe(expected.length); + }); + + expected.forEach((val: TestModel, index: number) => { + it(`should check expected results for
at position ${index}`, () => { + expect(des[index].nativeElement.style['flex-direction']).toBe(val.direction); + expect(des[index].nativeElement.style['justify-content']).toBe(val.justify); + }); + }); + + it('should check expected results for bare
without this directive', () => { + expect(bareElement.properties.ksDirection).toBeUndefined(); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/direction.directive.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/direction.directive.ts new file mode 100644 index 00000000..73940b4a --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/direction.directive.ts @@ -0,0 +1,76 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Directive, ElementRef, Input, OnChanges, OnInit, Renderer2 } from '@angular/core'; + +/** + * Directive to change the flex-direction of an element, based on two inputs (`direction` and `justify`). + */ +@Directive({ + selector: '[ksDirection]', + standalone: false +}) +export class DirectionDirective implements OnInit, OnChanges { + /** + * String input to set the css flex-direction of an element. + */ + @Input() + direction: string | undefined; + /** + * String input to set the css justify-content of an element. + */ + @Input() + justify: string | undefined; + + constructor(private renderer: Renderer2, private el: ElementRef) {} + + /** + * Method ´ngOnInit´ to apply the style of this directive. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called only one time!!! + */ + ngOnInit(): void { + this.applyStyle(); + } + + /** + * Method ´ngOnChanges´ to apply the style of this directive. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called when any data-bound property of a directive changes!!! + */ + ngOnChanges(): void { + this.applyStyle(); + } + + /** + * Private method to change both direction and justify of an element. + */ + private applyStyle(): void { + if (!this.direction || !this.justify) { + return; + } + this.renderer.setStyle(this.el.nativeElement, 'flex-direction', this.direction); + this.renderer.setStyle(this.el.nativeElement, 'justify-content', this.justify); + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/directives.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/directives.ts new file mode 100644 index 00000000..ab8990e2 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/directives.ts @@ -0,0 +1,52 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { ClickOutsideDirective } from './click-outside.directive'; +import { SizeDirective } from './size.directive'; +import { KeyboardNavigationDirective } from './keyboard-navigation.directive'; +import { WrapDirective } from './wrap.directive'; +import { DirectionDirective } from './direction.directive'; +import { ATagBgImageDirective } from './a-tag-bg-image.directive'; +import { DescriptionDirective } from './description.directive'; +import { MarginDirective } from './margin.directive'; +import { MaxSizeDirective } from './max-size.directive'; +import { FallbackImageDirective } from './fallback-image.directive'; +import { SwipeDirective } from './swipe.directive'; + +/** + * Array of all directives. + */ +export const DIRECTIVES = [ + ClickOutsideDirective, + SizeDirective, + KeyboardNavigationDirective, + WrapDirective, + DirectionDirective, + ATagBgImageDirective, + DescriptionDirective, + MarginDirective, + MaxSizeDirective, + FallbackImageDirective, + SwipeDirective +]; diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/fallback-image.directive.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/fallback-image.directive.spec.ts new file mode 100644 index 00000000..bb7b7f05 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/fallback-image.directive.spec.ts @@ -0,0 +1,154 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component, DebugElement, EventEmitter, Output } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By, SafeResourceUrl } from '@angular/platform-browser'; +import { FallbackImageDirective } from './fallback-image.directive'; + +@Component({ + selector: 'ks-test-fallback-image', + template: ` + + + + + + `, + standalone: false +}) +class TestFallbackImageComponent { + base64: SafeResourceUrl = 'data:image/png;base64,iVBORw0KG='; + imgPath = 'http:/example.com/bad-url.jpg'; + + @Output() + fallbackApplied: EventEmitter = new EventEmitter(); + + onError(data: boolean): void { + this.fallbackApplied.emit(data); + } +} + +@Component({ + selector: 'ks-test-fallback-image-wrong', + template: ` + + + + + + `, + standalone: false +}) +class WrongTestFallbackImageComponent { + @Output() + fallbackApplied: EventEmitter = new EventEmitter(); + + onError(data: boolean): void { + this.fallbackApplied.emit(data); + } +} + +let fixture: ComponentFixture; +let comp: TestFallbackImageComponent; +let des: DebugElement[] = []; +let bareElement: DebugElement; + +let fixtureWrong: ComponentFixture; +let compWrong: WrongTestFallbackImageComponent; +let desWrong: DebugElement[] = []; +let bareElementWrong: DebugElement; + +describe('FallbackImageDirective', () => { + + describe('---OK---', () => { + + beforeEach(() => { + TestBed.resetTestingModule(); + TestBed.configureTestingModule({ + declarations: [TestFallbackImageComponent, FallbackImageDirective] + }); // not necessary with webpack .compileComponents(); + fixture = TestBed.createComponent(TestFallbackImageComponent); + comp = fixture.componentInstance; + + fixture.detectChanges(); + return fixture.whenStable().then(() => { + fixture.detectChanges(); + bareElement = fixture.debugElement.query(By.css('img:not(ksFallbackImage)')); + des = fixture.debugElement.queryAll(By.directive(FallbackImageDirective)); + }); + }); + + it('can instantiate it', () => expect(comp).not.toBeNull()); + + it('should have this directive', () => { + expect(des.length).toBe(5); + }); + + it(`should return true, because fallbackImg is valid`, () => { + comp.fallbackApplied.subscribe((result: boolean) => { + expect(result).toBeTrue(); + }); + }); + + it('should check expected results for bare without this directive', () => { + expect(bareElement.properties.ksFallbackImage).toBeUndefined(); + }); + }); + + describe('---NO---', () => { + + beforeEach(() => { + TestBed.resetTestingModule(); + TestBed.configureTestingModule({ + declarations: [WrongTestFallbackImageComponent, FallbackImageDirective] + }); // not necessary with webpack .compileComponents(); + fixtureWrong = TestBed.createComponent(WrongTestFallbackImageComponent); + compWrong = fixtureWrong.componentInstance; + + fixtureWrong.detectChanges(); + return fixtureWrong.whenStable().then(() => { + fixtureWrong.detectChanges(); + bareElementWrong = fixtureWrong.debugElement.query(By.css('img:not(ksFallbackImage)')); + desWrong = fixtureWrong.debugElement.queryAll(By.directive(FallbackImageDirective)); + }); + }); + + it('can instantiate it', () => expect(compWrong).not.toBeNull()); + + it('should have this directive', () => { + expect(desWrong.length).toBe(5); + }); + + it(`should return false, because fallbackImg is not valid`, () => { + compWrong.fallbackApplied.subscribe((result: boolean) => { + expect(result).toBeFalse(); + }); + }); + + it('should check expected results for bare without this directive', () => { + expect(bareElementWrong.properties.ksFallbackImage).toBeUndefined(); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/fallback-image.directive.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/fallback-image.directive.ts new file mode 100644 index 00000000..b458d2d7 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/fallback-image.directive.ts @@ -0,0 +1,52 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Directive, ElementRef, EventEmitter, HostListener, Input, Output, Renderer2 } from '@angular/core'; +import { SafeResourceUrl } from '@angular/platform-browser'; + +/** + * Directive to add fallback image if the original one is not reachable. + */ +@Directive({ + selector: '[ksFallbackImage]', + standalone: false +}) +export class FallbackImageDirective { + @Input() + fallbackImg: string | SafeResourceUrl | undefined; + + @Output() + fallbackApplied: EventEmitter = new EventEmitter(); + + constructor(private renderer: Renderer2, private el: ElementRef) {} + + @HostListener('error') onError(): void { + if (!this.fallbackImg) { + this.fallbackApplied.emit(false); + return; + } + this.renderer.setAttribute(this.el.nativeElement, 'src', this.fallbackImg.toString()); + this.fallbackApplied.emit(true); + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/keyboard-navigation.directive.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/keyboard-navigation.directive.spec.ts new file mode 100644 index 00000000..cf29ca99 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/keyboard-navigation.directive.spec.ts @@ -0,0 +1,152 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component, DebugElement, EventEmitter, Output } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; + +import { KeyboardNavigationDirective } from './keyboard-navigation.directive'; + +@Component({ + selector: 'ks-test-keyboard-navigation', + template: ` +
+ `, + standalone: false +}) +class TestKeyboardNavigationComponent { + @Output() keyPress: EventEmitter = new EventEmitter(); + + onKeyPress(event: string) { + this.keyPress.emit(event); + } +} + +let fixture: ComponentFixture; +let comp: TestKeyboardNavigationComponent; +let des: DebugElement[] = []; +let directive: KeyboardNavigationDirective; + +describe('KeyboardNavigationDirective', () => { + beforeEach(() => { + TestBed.resetTestingModule(); + TestBed.configureTestingModule({ + declarations: [TestKeyboardNavigationComponent, KeyboardNavigationDirective] + }); // not necessary with webpack .compileComponents(); + + fixture = TestBed.createComponent(TestKeyboardNavigationComponent); + comp = fixture.componentInstance; + + fixture.detectChanges(); + return fixture.whenStable().then(() => { + fixture.detectChanges(); + des = fixture.debugElement.queryAll(By.directive(KeyboardNavigationDirective)); + directive = des[0].injector.get(KeyboardNavigationDirective); + }); + }); + + it('can instantiate it', () => expect(comp).not.toBeNull()); + + it('should have this directive', () => { + expect(des.length).toBe(1); + }); + + describe('---tests---', () => { + beforeEach(() => fixture.detectChanges()); + + it(`should check for this directive`, () => { + const clickOutsideDirective: DebugElement = fixture.debugElement.query(By.directive(KeyboardNavigationDirective)); + expect(clickOutsideDirective.name).toBe('main'); + expect(clickOutsideDirective.attributes['ksKeyboardNavigation']).toBe(''); + }); + + it(`should close the modal gallery after a click`, () => { + directive.isOpen = true; + fixture.detectChanges(); + comp.keyPress.subscribe((res: string) => { + expect(res).toBe('Escape'); + }); + const keydownEvent = new KeyboardEvent('keydown', { + code: 'Escape', + key: 'Escape', + altKey: false, + ctrlKey: false, + shiftKey: false, + metaKey: false + }); + window.dispatchEvent(keydownEvent); + }); + + it(`should navigate to the left when you press left arrow keyboard button`, () => { + directive.isOpen = true; + fixture.detectChanges(); + comp.keyPress.subscribe((res: string) => { + expect(res).toBe('Left'); + }); + const keydownEvent = new KeyboardEvent('keydown', { + code: 'Left', + key: 'Left', + altKey: false, + ctrlKey: false, + shiftKey: false, + metaKey: false + }); + window.dispatchEvent(keydownEvent); + }); + + it(`should navigate to the right when you press right arrow keyboard button`, () => { + directive.isOpen = true; + fixture.detectChanges(); + comp.keyPress.subscribe((res: string) => { + expect(res).toBe('Right'); + }); + const keydownEvent = new KeyboardEvent('keydown', { + code: 'Right', + key: 'Right', + altKey: false, + ctrlKey: false, + shiftKey: false, + metaKey: false + }); + window.dispatchEvent(keydownEvent); + }); + + it(`shouldn't close the modal gallery after a click, because isOpen is false`, () => { + directive.isOpen = false; + fixture.detectChanges(); + comp.keyPress.subscribe(() => { + fail('if isOpen = false there will be no clicked events'); + }); + const keydownEvent = new KeyboardEvent('keydown', { + code: 'Escape', + key: 'Escape', + altKey: false, + ctrlKey: false, + shiftKey: false, + metaKey: false + }); + window.dispatchEvent(keydownEvent); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/keyboard-navigation.directive.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/keyboard-navigation.directive.ts new file mode 100644 index 00000000..d0bacc69 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/keyboard-navigation.directive.ts @@ -0,0 +1,60 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Directive, EventEmitter, HostListener, Input, Output } from '@angular/core'; + +/** + * Directive to manage keyboard navigation. + */ +@Directive({ + selector: '[ksKeyboardNavigation]', + standalone: false +}) +export class KeyboardNavigationDirective { + /** + * Boolean input to skip keyboard navigation. + */ + @Input() + isOpen: boolean | undefined; + + /** + * Output to emit keyboard `code` of the pressed key (keydown). + */ + @Output() + keyboardNavigation: EventEmitter = new EventEmitter(); + + /** + * Listener to catch keyboard's events and call the right method based on the key. + * For instance, pressing esc, this will call `closeGallery(Action.KEYBOARD)` and so on. + * If you passed a valid `keyboardConfig` esc, right and left buttons will be customized based on your data. + * @param e KeyboardEvent caught by the listener. + */ + @HostListener('window:keydown', ['$event']) + onKeyDown(e: KeyboardEvent): void { + if (!this.isOpen) { + return; + } + this.keyboardNavigation.emit(e.code); + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/margin.directive.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/margin.directive.spec.ts new file mode 100644 index 00000000..2873fa5c --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/margin.directive.spec.ts @@ -0,0 +1,127 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component, DebugElement } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { MarginDirective } from './margin.directive'; + +interface Margin { + left?: string; + right?: string; + top?: string; + bottom?: string; +} + +const expected: Margin[] = [ + { left: '2px', right: '2px' }, + { left: '4px', right: '0px' }, + { left: '4px', right: '0px' }, + { left: '', right: '' }, + { left: '-2px', right: '-3px' }, + { top: '2px', bottom: '2px' }, + { top: '', bottom: '' }, + { top: '0px', bottom: '2px' }, + { top: '0px', bottom: '-7px' }, + { left: '2px', right: '2px', top: '0px', bottom: '2px' }, + // @ts-ignore + { left: undefined, right: null, top: undefined, bottom: null }, + {} +]; + +@Component({ + selector: 'ks-test-margin', + template: ` +
+
+
+
+
+
+
+
+
+
+
+
+ `, + standalone: false +}) +class TestMarginComponent {} + +let fixture: ComponentFixture; +let comp: TestMarginComponent; +let des: DebugElement[] = []; +let bareElement: DebugElement; + +describe('MarginDirective', () => { + + beforeEach(() => { + TestBed.resetTestingModule(); + TestBed.configureTestingModule({ + declarations: [TestMarginComponent, MarginDirective] + }); // not necessary with webpack .compileComponents(); + fixture = TestBed.createComponent(TestMarginComponent); + comp = fixture.componentInstance; + + fixture.detectChanges(); + return fixture.whenStable().then(() => { + fixture.detectChanges(); + bareElement = fixture.debugElement.query(By.css('div:not(ksMargin)')); + des = fixture.debugElement.queryAll(By.directive(MarginDirective)); + }); + }); + + it('can instantiate it', () => expect(comp).not.toBeNull()); + + describe('---tests---', () => { + + beforeEach(() => fixture.detectChanges()); + + it('should have this directive', () => { + expect(des.length).toBe(expected.length); + }); + + expected.forEach((val: Margin, index: number) => { + it(`should check expected results for
at position ${index}`, () => { + if (val.left) { + expect(des[index].nativeElement.style.marginLeft).toBe(val.left); + } + if (val.right) { + expect(des[index].nativeElement.style.marginRight).toBe(val.right); + } + if (val.top) { + expect(des[index].nativeElement.style.marginTop).toBe(val.top); + } + if (val.bottom) { + expect(des[index].nativeElement.style.marginBottom).toBe(val.bottom); + } + }); + }); + + it('should check expected results for bare
without this directive', () => { + expect(bareElement.properties.ksMargin).toBeUndefined(); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/margin.directive.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/margin.directive.ts new file mode 100644 index 00000000..aed1d083 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/margin.directive.ts @@ -0,0 +1,93 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Directive, ElementRef, Input, OnChanges, OnInit, Renderer2 } from '@angular/core'; + +/** + * Directive to change margins of an element. + */ +@Directive({ + selector: '[ksMargin]', + standalone: false +}) +export class MarginDirective implements OnInit, OnChanges { + /** + * String to set the margin of an element. + */ + @Input() + marginLeft: string | undefined; + /** + * String to set the margin of an element. + */ + @Input() + marginRight: string | undefined; + /** + * String to set the margin of an element. + */ + @Input() + marginTop: string | undefined; + /** + * String to set the margin of an element. + */ + @Input() + marginBottom: string | undefined; + + constructor(private renderer: Renderer2, private el: ElementRef) {} + + /** + * Method ´ngOnInit´ to apply the style of this directive. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called only one time!!! + */ + ngOnInit(): void { + this.applyStyle(); + } + + /** + * Method ´ngOnChanges´ to apply the style of this directive. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called when any data-bound property of a directive changes!!! + */ + ngOnChanges(): void { + this.applyStyle(); + } + + /** + * Private method to change both width and height of an element. + */ + private applyStyle(): void { + if (this.marginLeft) { + this.renderer.setStyle(this.el.nativeElement, 'margin-left', this.marginLeft); + } + if (this.marginRight) { + this.renderer.setStyle(this.el.nativeElement, 'margin-right', this.marginRight); + } + if (this.marginTop) { + this.renderer.setStyle(this.el.nativeElement, 'margin-top', this.marginTop); + } + if (this.marginBottom) { + this.renderer.setStyle(this.el.nativeElement, 'margin-bottom', this.marginBottom); + } + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/max-size.directive.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/max-size.directive.spec.ts new file mode 100644 index 00000000..5e86f252 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/max-size.directive.spec.ts @@ -0,0 +1,98 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component, DebugElement } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { MaxSizeDirective } from './max-size.directive'; +import { MaxSize } from '../model/max-size.interface'; + +const expected: MaxSize[] = [ + {maxWidth: '100px', maxHeight: '80px'}, + {maxWidth: '50px', maxHeight: '20px'}, + {maxWidth: '50%', maxHeight: '100%'}, + {maxWidth: '', maxHeight: ''}, + {} +]; + +@Component({ + selector: 'ks-test-max-size', + template: ` +
+
+
+
+
+ `, + standalone: false +}) +class TestSizeComponent {} + +let fixture: ComponentFixture; +let comp: TestSizeComponent; +let des: DebugElement[] = []; +let bareElement: DebugElement; + +describe('MaxSizeDirective', () => { + + beforeEach(() => { + TestBed.resetTestingModule(); + TestBed.configureTestingModule({ + declarations: [TestSizeComponent, MaxSizeDirective] + }); // not necessary with webpack .compileComponents(); + fixture = TestBed.createComponent(TestSizeComponent); + comp = fixture.componentInstance; + + fixture.detectChanges(); + return fixture.whenStable().then(() => { + fixture.detectChanges(); + bareElement = fixture.debugElement.query(By.css('div:not(ksMaxSize)')); + des = fixture.debugElement.queryAll(By.directive(MaxSizeDirective)); + }); + }); + + it('can instantiate it', () => expect(comp).not.toBeNull()); + + describe('---tests---', () => { + + beforeEach(() => fixture.detectChanges()); + + it('should have this directive', () => { + expect(des.length).toBe(expected.length); + }); + + expected.forEach((val: MaxSize, index: number) => { + it(`should check expected results for
at position ${index}`, () => { + // I'm using `|| ''` because it's not possible to have undefined inside css, + // instead my MaxSize interface have all its fields optional, so they can be undefined. + expect(des[index].nativeElement.style['max-width']).toBe(val.maxWidth || ''); + expect(des[index].nativeElement.style['max-height']).toBe(val.maxHeight || ''); + }); + }); + + it('should check expected results for bare
without this directive', () => { + expect(bareElement.properties.ksMaxSize).toBeUndefined(); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/max-size.directive.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/max-size.directive.ts new file mode 100644 index 00000000..7b2a925f --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/max-size.directive.ts @@ -0,0 +1,76 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Directive, ElementRef, Input, OnChanges, OnInit, Renderer2 } from '@angular/core'; +import { MaxSize } from '../model/max-size.interface'; + +/** + * Directive to change the max size of an element. + */ +@Directive({ + selector: '[ksMaxSize]', + standalone: false +}) +export class MaxSizeDirective implements OnInit, OnChanges { + /** + * Object of type `MaxSize` to resize the element. + */ + @Input() + maxSizeConfig: MaxSize | undefined; + + constructor(private renderer: Renderer2, private el: ElementRef) {} + + /** + * Method ´ngOnInit´ to apply the style of this directive. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called only one time!!! + */ + ngOnInit(): void { + this.applyStyle(); + } + + /** + * Method ´ngOnChanges´ to apply the style of this directive. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called when any data-bound property of a directive changes!!! + */ + ngOnChanges(): void { + this.applyStyle(); + } + + /** + * Private method to change both max-width and max-height of an element. + */ + private applyStyle(): void { + if (!this.maxSizeConfig) { + return; + } + if (this.maxSizeConfig.maxWidth) { + this.renderer.setStyle(this.el.nativeElement, 'max-width', this.maxSizeConfig.maxWidth); + } + if (this.maxSizeConfig.maxHeight) { + this.renderer.setStyle(this.el.nativeElement, 'max-height', this.maxSizeConfig.maxHeight); + } + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/size.directive.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/size.directive.spec.ts new file mode 100644 index 00000000..aae12bb0 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/size.directive.spec.ts @@ -0,0 +1,102 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component, DebugElement } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { SizeDirective } from './size.directive'; +import { Size } from '../model/size.interface'; + +const expected: Size[] = [ + {width: '100px', height: '80px'}, + {width: '50px', height: '20px'}, + {width: '50%', height: '100%'}, + {width: 'auto', height: 'auto'}, + {width: 'auto', height: '20px'}, + {width: '50px', height: 'auto'}, + {width: '', height: ''}, + {width: '', height: ''} +]; + +@Component({ + selector: 'ks-test-size', + template: ` +
+
+
+
+
+
+
+
+ `, + standalone: false +}) +class TestSizeComponent {} + +let fixture: ComponentFixture; +let comp: TestSizeComponent; +let des: DebugElement[] = []; +let bareElement: DebugElement; + +describe('SizeDirective', () => { + + beforeEach(() => { + TestBed.resetTestingModule(); + TestBed.configureTestingModule({ + declarations: [TestSizeComponent, SizeDirective] + }); // not necessary with webpack .compileComponents(); + fixture = TestBed.createComponent(TestSizeComponent); + comp = fixture.componentInstance; + + fixture.detectChanges(); + return fixture.whenStable().then(() => { + fixture.detectChanges(); + bareElement = fixture.debugElement.query(By.css('div:not(ksSize)')); + des = fixture.debugElement.queryAll(By.directive(SizeDirective)); + }); + }); + + it('can instantiate it', () => expect(comp).not.toBeNull()); + + describe('---tests---', () => { + + beforeEach(() => fixture.detectChanges()); + + it('should have this directive', () => { + expect(des.length).toBe(expected.length); + }); + + expected.forEach((val: Size, index: number) => { + it(`should check expected results for
at position ${index}`, () => { + expect(des[index].nativeElement.style.width).toBe(val.width); + expect(des[index].nativeElement.style.height).toBe(val.height); + }); + }); + + it('should check expected results for bare
without this directive', () => { + expect(bareElement.properties.ksSize).toBeUndefined(); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/size.directive.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/size.directive.ts new file mode 100644 index 00000000..55e54792 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/size.directive.ts @@ -0,0 +1,77 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Directive, ElementRef, Input, OnChanges, OnInit, Renderer2 } from '@angular/core'; +import { Size } from '../model/size.interface'; + +/** + * Directive to change the size of an element. + */ +@Directive({ + selector: '[ksSize]', + standalone: false +}) +export class SizeDirective implements OnInit, OnChanges { + /** + * Object of type `Size` to resize the element. + */ + @Input() + sizeConfig: Size | undefined; + + constructor(private renderer: Renderer2, private el: ElementRef) {} + + /** + * Method ´ngOnInit´ to apply the style of this directive. + * This is an Angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called only one time!!! + */ + ngOnInit(): void { + this.applyStyle(); + } + + /** + * Method ´ngOnChanges´ to apply the style of this directive. + * This is an Angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called when any data-bound property of a directive changes!!! + */ + ngOnChanges(): void { + this.applyStyle(); + } + + /** + * Private method to change both width and height of an element. + */ + private applyStyle(): void { + if (!this.sizeConfig) { + return; + } + // apply [style.width] + if (this.sizeConfig.width) { + this.renderer.setStyle(this.el.nativeElement, 'width', this.sizeConfig.width); + } + if (this.sizeConfig.height) { + this.renderer.setStyle(this.el.nativeElement, 'height', this.sizeConfig.height); + } + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/swipe.directive.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/swipe.directive.ts new file mode 100644 index 00000000..6e741249 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/swipe.directive.ts @@ -0,0 +1,104 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Directive, EventEmitter, HostListener, Input, Output } from '@angular/core'; + + +// Inspired from https://stackblitz.com/edit/angular-swipe-events-with-hostlistner?file=src%2Fapp%2Fapp.component.ts + +/** + * Directive to manage swipe events on touch devices. + */ +@Directive({ + selector: '[ksSwipe]', + standalone: false +}) +export class SwipeDirective { + defaultTouch = { x: 0, y: 0, time: 0 }; + + /** + * Output to emit swipe left event. Payload is empty. + */ + @Output() + swipeLeft: EventEmitter = new EventEmitter(); + /** + * Output to emit swipe right event. Payload is empty. + */ + @Output() + swipeRight: EventEmitter = new EventEmitter(); + /** + * Output to emit swipe up event. Payload is empty. + */ + @Output() + swipeUp: EventEmitter = new EventEmitter(); + /** + * Output to emit swipe down event. Payload is empty. + */ + @Output() + swipeDown: EventEmitter = new EventEmitter(); + + /** + * Method called by Angular itself every click thanks to `@HostListener`. + * @param event TouchEvent payload received on touch + */ + @HostListener('touchstart', ['$event']) + @HostListener('touchend', ['$event']) + @HostListener('touchcancel', ['$event']) + handleTouch(event: TouchEvent) { + let touch = event.touches[0] || event.changedTouches[0]; + // check the events + if (event.type === 'touchstart') { + this.defaultTouch.x = touch.pageX; + this.defaultTouch.y = touch.pageY; + this.defaultTouch.time = event.timeStamp; + } else if (event.type === 'touchend') { + let deltaX = touch.pageX - this.defaultTouch.x; + let deltaY = touch.pageY - this.defaultTouch.y; + let deltaTime = event.timeStamp - this.defaultTouch.time; + + // simulate a swipe -> less than 500 ms and more than 60 px + if (deltaTime < 500) { + // touch movement lasted less than 500 ms + if (Math.abs(deltaX) > 60) { + // delta x is at least 60 pixels + if (deltaX > 0) { + this.swipeRight.emit(); + } else { + this.swipeLeft.emit(); + } + } + + if (Math.abs(deltaY) > 60) { + // delta y is at least 60 pixels + if (deltaY > 0) { + this.swipeDown.emit(); + } else { + this.swipeUp.emit(); + } + } + } + } + } + +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/wrap.directive.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/wrap.directive.spec.ts new file mode 100644 index 00000000..0a303be5 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/wrap.directive.spec.ts @@ -0,0 +1,96 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ +import { Component, DebugElement } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { WrapDirective } from './wrap.directive'; + +interface TestModel { + width: string; + wrap: boolean | undefined; + wrapStyle: string; +} + +@Component({ + selector: 'ks-test-wrap', + template: ` +
+
+
+ `, + standalone: false +}) +class TestWrapComponent {} + +let fixture: ComponentFixture; +let comp: TestWrapComponent; +let des: DebugElement[] = []; +let bareElement: DebugElement; + +const expected: TestModel[] = [ + {width: '100px', wrap: true, wrapStyle: 'wrap'}, + {width: '', wrap: false, wrapStyle: ''}, + {width: '', wrap: undefined, wrapStyle: ''}, +]; + +describe('WrapDirective', () => { + + beforeEach(() => { + TestBed.resetTestingModule(); + TestBed.configureTestingModule({ + declarations: [TestWrapComponent, WrapDirective] + }); // not necessary with webpack .compileComponents(); + fixture = TestBed.createComponent(TestWrapComponent); + comp = fixture.componentInstance; + + fixture.detectChanges(); + return fixture.whenStable().then(() => { + fixture.detectChanges(); + bareElement = fixture.debugElement.query(By.css('div:not(ksWrap)')); + des = fixture.debugElement.queryAll(By.directive(WrapDirective)); + }); + }); + + it('can instantiate it', () => expect(comp).not.toBeNull()); + + describe('---tests---', () => { + + beforeEach(() => fixture.detectChanges()); + + it('should have this directive', () => { + expect(des.length).toBe(3); + }); + + expected.forEach((val: TestModel, index: number) => { + it(`should check expected results for
at position ${index}`, () => { + expect(des[index].nativeElement.style.width).toBe(val.width); + expect(des[index].nativeElement.style['flex-wrap']).toBe(val.wrapStyle); + }); + }); + + it('should check expected results for bare
without this directive', () => { + expect(bareElement.properties.ksWrap).toBeUndefined(); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/directives/wrap.directive.ts b/projects/ks89/angular-modal-gallery/src/lib/directives/wrap.directive.ts new file mode 100644 index 00000000..d7f967da --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/directives/wrap.directive.ts @@ -0,0 +1,77 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Directive, ElementRef, Input, OnChanges, OnInit, Renderer2 } from '@angular/core'; + +/** + * Directive to change the flex-wrap css property of an element. + */ +@Directive({ + selector: '[ksWrap]', + standalone: false +}) +export class WrapDirective implements OnInit, OnChanges { + /** + * Boolean input that it's true to add 'flex-wrap: wrap', 'flex-wrap: nowrap' otherwise. + */ + @Input() + wrap: boolean | undefined; + /** + * String input to force the width of the element to be able to see wrapping. + */ + @Input() + width: string | undefined; + + constructor(private renderer: Renderer2, private el: ElementRef) {} + + /** + * Method ´ngOnInit´ to apply the style of this directive. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called only one time!!! + */ + ngOnInit(): void { + this.applyStyle(); + } + + /** + * Method ´ngOnChanges´ to apply the style of this directive. + * This is an angular lifecycle hook, so its called automatically by Angular itself. + * In particular, it's called when any data-bound property of a directive changes!!! + */ + ngOnChanges(): void { + this.applyStyle(); + } + + /** + * Private method to change both width and flex-wrap css properties. + */ + private applyStyle(): void { + // TODO is this right???? If wrap is false I cannot apply width and flex-wrap + if (!this.wrap) { + return; + } + this.renderer.setStyle(this.el.nativeElement, 'width', this.width); + this.renderer.setStyle(this.el.nativeElement, 'flex-wrap', this.wrap ? 'wrap' : 'nowrap'); + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/modal-gallery.module.ts b/projects/ks89/angular-modal-gallery/src/lib/modal-gallery.module.ts new file mode 100644 index 00000000..c94dc5f1 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/modal-gallery.module.ts @@ -0,0 +1,52 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { APP_INITIALIZER, NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { OverlayModule } from '@angular/cdk/overlay'; + +import { COMPONENTS, CarouselComponent } from './components/components'; +import { PlainGalleryComponent } from './components/plain-gallery/plain-gallery.component'; +import { DIRECTIVES } from './directives/directives'; +import { AttachToOverlayService } from './components/modal-gallery/attach-to-overlay.service'; + +/** + * Module to import it in the root module of your application. + */ +@NgModule({ + imports: [CommonModule, OverlayModule], + declarations: [COMPONENTS, DIRECTIVES], + providers: [ + { + provide: APP_INITIALIZER, + multi: true, + deps: [AttachToOverlayService], + useFactory: (service: AttachToOverlayService): (() => void) => { + return () => service.initialize(); + } + } + ], + exports: [PlainGalleryComponent, CarouselComponent] +}) +export class GalleryModule {} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/accessibility.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/accessibility.interface.ts new file mode 100644 index 00000000..5193b3af --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/accessibility.interface.ts @@ -0,0 +1,71 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +/** + * Interface `Accessibility` to config titles, alt texts, aria labels and so on + */ +export interface AccessibilityConfig { + backgroundAriaLabel: string; + backgroundTitle: string; + + plainGalleryContentAriaLabel: string; + plainGalleryContentTitle: string; + + modalGalleryContentAriaLabel: string; + modalGalleryContentTitle: string; + + loadingSpinnerAriaLabel: string; + loadingSpinnerTitle: string; + + mainContainerAriaLabel: string; + mainContainerTitle: string; + mainPrevImageAriaLabel: string; + mainPrevImageTitle: string; + mainNextImageAriaLabel: string; + mainNextImageTitle: string; + + dotsContainerAriaLabel: string; + dotsContainerTitle: string; + dotAriaLabel: string; + + previewsContainerAriaLabel: string; + previewsContainerTitle: string; + previewScrollPrevAriaLabel: string; + previewScrollPrevTitle: string; + previewScrollNextAriaLabel: string; + previewScrollNextTitle: string; + + carouselContainerAriaLabel: string; + carouselContainerTitle: string; + carouselPrevImageAriaLabel: string; + carouselPrevImageTitle: string; + carouselNextImageAriaLabel: string; + carouselNextImageTitle: string; + carouselPreviewsContainerAriaLabel: string; + carouselPreviewsContainerTitle: string; + carouselPreviewScrollPrevAriaLabel: string; + carouselPreviewScrollPrevTitle: string; + carouselPreviewScrollNextAriaLabel: string; + carouselPreviewScrollNextTitle: string; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/action.enum.ts b/projects/ks89/angular-modal-gallery/src/lib/model/action.enum.ts new file mode 100644 index 00000000..513df1a1 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/action.enum.ts @@ -0,0 +1,35 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +/** + * Enum `Action` with a list of possible actions, based on the source of the action. + */ +export enum Action { + NORMAL, // default value + CLICK, // mouse click + KEYBOARD, + SWIPE, + LOAD, + AUTOPLAY +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/buttons-config.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/buttons-config.interface.ts new file mode 100644 index 00000000..b102ab25 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/buttons-config.interface.ts @@ -0,0 +1,98 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Action } from './action.enum'; +import { InternalLibImage } from './image-internal.class'; +import { Size } from './size.interface'; + +/** + * Interface `ButtonsConfig` to add buttons, show/hide their, and to add the strategy. + */ +export interface ButtonsConfig { + visible: boolean; + strategy: ButtonsStrategy; + buttons?: ButtonConfig[]; +} + +/** + * Interface `ButtonConfig` to configure a single button. + */ +export interface ButtonConfig { + className?: string; + size?: Size; + fontSize?: string; + type: ButtonType; + title?: string; + ariaLabel?: string; + extUrlInNewTab?: boolean; // to open the external url in a new tab, instead of the current one +} + +/** + * Interface `ButtonEvent` to represent the event payload when a button is clicked. + */ +export interface ButtonEvent { + button: ButtonConfig; + image: InternalLibImage | null; + action: Action; + galleryId: number; +} + +/** + * Enum `ButtonsStrategy` to configure the logic of a button. + */ +export enum ButtonsStrategy { + // don't use 0 here + // the first index is 1 and all of the following members are auto-incremented from that point on + DEFAULT = 1, + SIMPLE, + ADVANCED, + FULL, + CUSTOM +} + +/** + * Enum `ButtonType` is the type of a button. + */ +export enum ButtonType { + // don't use 0 here + // the first index is 1 and all of the following members are auto-incremented from that point on + DELETE = 1, + EXTURL, + DOWNLOAD, + CLOSE, + CUSTOM, + FULLSCREEN +} + +/** + * Array of admitted types of buttons. + */ +export const WHITELIST_BUTTON_TYPES: ButtonType[] = [ + ButtonType.FULLSCREEN, + ButtonType.DELETE, + ButtonType.EXTURL, + ButtonType.DOWNLOAD, + ButtonType.CLOSE, + ButtonType.CUSTOM +]; diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/carousel-config.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/carousel-config.interface.ts new file mode 100644 index 00000000..5bf2a59b --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/carousel-config.interface.ts @@ -0,0 +1,35 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +/** + * Interface `CarouselConfig` to change the style of the carousel and some additional features. + */ +export interface CarouselConfig { + maxWidth: string; + maxHeight: string; + showArrows: boolean; + objectFit: string; + keyboardEnable: boolean; + modalGalleryEnable: boolean; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/carousel-image-config.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/carousel-image-config.interface.ts new file mode 100644 index 00000000..1d309e0c --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/carousel-image-config.interface.ts @@ -0,0 +1,33 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Description } from './description.interface'; + +/** + * Interface `CarouselImageConfig` to change current image behaviour in carousel. + */ +export interface CarouselImageConfig { + description?: Description; + invertSwipe?: boolean; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/carousel-preview-config.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/carousel-preview-config.interface.ts new file mode 100644 index 00000000..3590f497 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/carousel-preview-config.interface.ts @@ -0,0 +1,49 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +/** + * Interface `BreakpointsConfig` to configure responsive breakpoints as numbers to express pixels + */ +export interface BreakpointsConfig { + xSmall: number; + small: number; + medium: number; + large: number; + xLarge: number; +} + +/** + * Interface `CarouselPreviewConfig` to configure carousel's previews + */ +export interface CarouselPreviewConfig { + visible: boolean; + number?: number; + arrows?: boolean; + clickable?: boolean; + width?: string; + // maxHeight is called in this way because it represents the maxHeight for users, however inside the code it's the height + // I called maxHeight because it's handled in a complex way also with Breakpoints and I'm using Math.min like is it's the maxHeight instead of the height + maxHeight?: string; + breakpoints?: BreakpointsConfig; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/current-image-config.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/current-image-config.interface.ts new file mode 100644 index 00000000..1765a5a5 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/current-image-config.interface.ts @@ -0,0 +1,38 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { LoadingConfig } from './loading-config.interface'; +import { Description } from './description.interface'; + +/** + * Interface `CurrentImageConfig` to change current image behaviour in modal-gallery. + */ +export interface CurrentImageConfig { + navigateOnClick?: boolean; + downloadable?: boolean; + loadingConfig?: LoadingConfig; + description?: Description; + // option to invert swipe direction (because for some users it's more natural) + invertSwipe?: boolean; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/description.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/description.interface.ts new file mode 100644 index 00000000..9d730b40 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/description.interface.ts @@ -0,0 +1,66 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +/** + * Interface `Description` to change the description, either with a full custom + * description or with a small and simple customization. + * Also, you could change margins, background style and so on. + */ +export interface Description { + strategy: DescriptionStrategy; + customFullDescription?: string; + imageText?: string; + numberSeparator?: string; + beforeTextDescription?: string; + + style?: DescriptionStyle; +} + +/** + * Enum `DescriptionStrategy` with keys and their relative key codes. + */ +export enum DescriptionStrategy { + ALWAYS_HIDDEN = 1, + ALWAYS_VISIBLE, + HIDE_IF_EMPTY +} + +/** + * Interface to change css properties. + */ +export interface DescriptionStyle { + bgColor?: string; + textColor?: string; + width?: string; + height?: string; + position?: string; + top?: string; + bottom?: string; + left?: string; + right?: string; + marginTop?: string; + marginBottom?: string; + marginRight?: string; + marginLeft?: string; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/dots-config.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/dots-config.interface.ts new file mode 100644 index 00000000..6170d1de --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/dots-config.interface.ts @@ -0,0 +1,30 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +/** + * Interface `DotsConfig` to show/hide dots. + */ +export interface DotsConfig { + visible: boolean; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/image-internal.class.ts b/projects/ks89/angular-modal-gallery/src/lib/model/image-internal.class.ts new file mode 100644 index 00000000..ced04a11 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/image-internal.class.ts @@ -0,0 +1,39 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Image, ModalImage, PlainImage } from './image.class'; + +/** + * Internal representation of an image adding other fields + * to the public `Image` class. + */ +export class InternalLibImage extends Image { + previouslyLoaded: boolean; + + constructor(id: number, modal: ModalImage, plain?: PlainImage, previouslyLoaded: boolean = false) { + super(id, modal, plain); + + this.previouslyLoaded = previouslyLoaded; + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/image.class.ts b/projects/ks89/angular-modal-gallery/src/lib/model/image.class.ts new file mode 100644 index 00000000..d7644315 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/image.class.ts @@ -0,0 +1,109 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Action } from './action.enum'; +import { Size } from './size.interface'; +import { SafeResourceUrl } from '@angular/platform-browser'; + +/** + * Class `Image` that represents an image with both `modal` and `plain` configurations. + * Both image `id` and `modal` are mandatory, instead `plain` is optional. + */ +export class Image { + id: number; + loading: 'eager' | 'lazy'; + fetchpriority: 'high' | 'low' | 'auto'; + modal: ModalImage; + plain?: PlainImage; + + constructor(id: number, modal: ModalImage, plain?: PlainImage, loading: 'eager' | 'lazy' = 'lazy', fetchpriority: 'high' | 'low' | 'auto' = 'auto') { + this.id = id; + this.modal = modal; + this.plain = plain; + this.loading = loading; + this.fetchpriority = fetchpriority + } +} + +/** + * Interface `ImageData` to configure an image, but it isn't used directly. + * Please, refers to `PlainImage` or `ModalImage`. + */ +export interface ImageData { + img: string | SafeResourceUrl; + description?: string; + title?: string; + alt?: string; + ariaLabel?: string; + fallbackImg?: string | SafeResourceUrl; +} + +/** + * Interface `ModalImage` to configure the modal image. + */ +export interface ModalImage extends ImageData { + extUrl?: string; + downloadFileName?: string; + sources?: Source[]; +} + +/** + * Interface `PlainImage` to configure the plain image. + */ +export interface PlainImage extends ImageData { + size?: Size; +} + +/** + * Class `ImageEvent` that represents the event payload with the result and the triggered action. + * It also contains the source id of the gallery that emitted this event + */ +export class ImageEvent { + galleryId: number; + action: Action; + result: number | boolean; + + constructor(galleryId: number, action: Action, result: number | boolean) { + this.galleryId = galleryId; + this.action = action; + this.result = result; + } +} + +/** + * Class `ImageModalEvent` that represents the event payload with galleryId, result and the triggered action. + */ +export class ImageModalEvent extends ImageEvent { + constructor(galleryId: number, action: Action, result: number | boolean) { + super(galleryId, action, result); + } +} + +/** + * Interface `Source` to configure sources of picture element. + */ +export interface Source { + srcset: string; + media: string; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/interaction-event.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/interaction-event.interface.ts new file mode 100644 index 00000000..e2fbfe7e --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/interaction-event.interface.ts @@ -0,0 +1,8 @@ +import { Action } from './action.enum'; + +export interface InteractionEvent { + source: string; + action: Action; + // tslint:disable-next-line:no-any + payload: any; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/keyboard-config.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/keyboard-config.interface.ts new file mode 100644 index 00000000..02cc616c --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/keyboard-config.interface.ts @@ -0,0 +1,32 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +/** + * Interface `KeyboardConfig` to assign custom codes to ESC, RIGHT and LEFT keyboard's actions. + */ +export interface KeyboardConfig { + esc?: string; + right?: string; + left?: string; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/keyboard.enum.ts b/projects/ks89/angular-modal-gallery/src/lib/model/keyboard.enum.ts new file mode 100644 index 00000000..8bc54142 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/keyboard.enum.ts @@ -0,0 +1,44 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +/** + * Enum `Keyboard` with keys and their relative codes. + */ +import { DOWN_ARROW_CODE, ESC_CODE, LEFT_ARROW_CODE, RIGHT_ARROW_CODE, UP_ARROW_CODE } from '../utils/user-input.util'; + +type Keyboard = Readonly<{ + ESC: typeof ESC_CODE, + LEFT_ARROW: typeof LEFT_ARROW_CODE, + RIGHT_ARROW: typeof RIGHT_ARROW_CODE, + UP_ARROW: typeof UP_ARROW_CODE, + DOWN_ARROW: typeof DOWN_ARROW_CODE +}>; + +export const Keyboard: Keyboard = { + ESC: ESC_CODE, + LEFT_ARROW: LEFT_ARROW_CODE, + RIGHT_ARROW: RIGHT_ARROW_CODE, + UP_ARROW: UP_ARROW_CODE, + DOWN_ARROW: DOWN_ARROW_CODE +}; diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/lib-config.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/lib-config.interface.ts new file mode 100644 index 00000000..0313cf41 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/lib-config.interface.ts @@ -0,0 +1,68 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { SlideConfig } from './slide-config.interface'; +import { AccessibilityConfig } from './accessibility.interface'; +import { PreviewConfig } from './preview-config.interface'; +import { ButtonsConfig } from './buttons-config.interface'; +import { DotsConfig } from './dots-config.interface'; +import { PlainGalleryConfig } from './plain-gallery-config.interface'; +import { CurrentImageConfig } from './current-image-config.interface'; +import { KeyboardConfig } from './keyboard-config.interface'; +import { CarouselConfig } from './carousel-config.interface'; +import { CarouselImageConfig } from './carousel-image-config.interface'; +import { CarouselPreviewConfig } from './carousel-preview-config.interface'; +import { PlayConfig } from './play-config.interface'; + +export interface AccessibleLibConfig { + accessibilityConfig?: AccessibilityConfig; +} + +export interface CommonLibConfig { + previewConfig?: PreviewConfig; + dotsConfig?: DotsConfig; + slideConfig?: SlideConfig; +} + +export interface CarouselLibConfig extends CommonLibConfig, AccessibleLibConfig { + carouselConfig?: CarouselConfig; + carouselImageConfig?: CarouselImageConfig; + carouselPreviewsConfig?: CarouselPreviewConfig; + carouselPlayConfig?: PlayConfig; + carouselDotsConfig?: DotsConfig; + carouselSlideInfinite?: boolean; +} + +export interface ModalLibConfig extends CommonLibConfig, AccessibleLibConfig { + enableCloseOutside?: boolean; + keyboardConfig?: KeyboardConfig; + currentImageConfig?: CurrentImageConfig; + buttonsConfig?: ButtonsConfig; +} + +export interface PlainLibConfig extends AccessibleLibConfig { + plainGalleryConfig?: PlainGalleryConfig; +} + +export interface LibConfig extends ModalLibConfig, PlainLibConfig, CarouselLibConfig {} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/loading-config.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/loading-config.interface.ts new file mode 100644 index 00000000..7c5dfe0c --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/loading-config.interface.ts @@ -0,0 +1,44 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +/** + * Interface `LoadingConfig` to configure loading icon. + */ +export interface LoadingConfig { + enable: boolean; + type: LoadingType; +} + +/** + * Enum `LoadingType` with a list of possible types. + */ +export enum LoadingType { + STANDARD = 1, + CIRCULAR, + BARS, + DOTS, + CUBE_FLIPPING, + CIRCLES, + EXPLOSING_SQUARES +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/max-size.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/max-size.interface.ts new file mode 100644 index 00000000..ea546697 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/max-size.interface.ts @@ -0,0 +1,32 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +/** + * Interface `MaxSize` to configure the size based on max-width and max-height. + * They can be pixels, percentages. + */ +export interface MaxSize { + maxWidth?: string; + maxHeight?: string; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/modal-gallery-config.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/modal-gallery-config.interface.ts new file mode 100644 index 00000000..960b93eb --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/modal-gallery-config.interface.ts @@ -0,0 +1,41 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { TemplateRef } from '@angular/core'; +import { Image } from './image.class'; +import { ModalLibConfig } from './lib-config.interface'; + +export interface ModalGalleryConfig { + id: number; + images: Image[]; + currentImage: Image; + libConfig?: ModalLibConfig; + /** + * Optional template reference for the rendering of previews. + * Template may access following context variables: + * - "preview": the `Image` object of the preview + * - "defaultTemplate": the template used by default to render the preview (in case the need is to augment it) + */ + previewsTemplate?: TemplateRef; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/plain-gallery-config.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/plain-gallery-config.interface.ts new file mode 100644 index 00000000..2a004bbd --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/plain-gallery-config.interface.ts @@ -0,0 +1,99 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Size } from './size.interface'; + +/** + * Interface `PlainGalleryConfig` to configure plain-gallery features. + */ +export interface PlainGalleryConfig { + strategy: PlainGalleryStrategy; + layout: PlainGalleryLayout; + advanced?: AdvancedConfig; +} + +/** + * Interface `PlainGalleryLayout` to configure the layout. This interface isn't used directly, instead + * refers to either `LineLayout`, `GridLayout`. + */ +// tslint:disable-next-line no-empty-interface +export interface PlainGalleryLayout {} + +/** + * Class `LineLayout` to configure a linear plain gallery. + */ +export class LineLayout implements PlainGalleryLayout { + breakConfig: BreakConfig; + justify: string; + size: Size; + + constructor(size: Size, breakConfig: BreakConfig, justify: string) { + this.size = size; + this.breakConfig = breakConfig; + this.justify = justify; + } +} + +/** + * Class `GridLayout` to configure a grid plain gallery. + */ +export class GridLayout implements PlainGalleryLayout { + breakConfig: BreakConfig; + size: Size; + + constructor(size: Size, breakConfig: BreakConfig) { + this.size = size; + this.breakConfig = breakConfig; + } +} + +/** + * Enum `PlainGalleryStrategy` to choose the behaviour of the plain gallery. + */ +export enum PlainGalleryStrategy { + // don't use 0 here + // the first index is 1 and all of the following members are auto-incremented from that point on + ROW = 1, + COLUMN, + GRID, + CUSTOM // full custom strategy +} + +/** + * Interface `BreakConfig` to limit the number of items of the plain gallery or to force it to fill other lines. + */ +export interface BreakConfig { + length: number; + wrap: boolean; +} + +/** + * Interface `AdvancedConfig` to use `` tags instead of ``. + * It also contains a string property to customize the css background property. + * For more info check here https://www.w3schools.com/cssref/css3_pr_background.asp + */ +export interface AdvancedConfig { + aTags: boolean; + additionalBackground: string; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/play-config.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/play-config.interface.ts new file mode 100644 index 00000000..060efa23 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/play-config.interface.ts @@ -0,0 +1,32 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +/** + * Interface `PlayConfig` to change the behaviour about auto-navigation for both modal gallery and carousel. + */ +export interface PlayConfig { + autoPlay: boolean; + interval: number; + pauseOnHover: boolean; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/preview-config.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/preview-config.interface.ts new file mode 100644 index 00000000..2a21d9e6 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/preview-config.interface.ts @@ -0,0 +1,38 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Size } from './size.interface'; + +/** + * Interface `PreviewConfig` to configure previews in modal gallery. + */ +export interface PreviewConfig { + visible: boolean; + // by default previews are hidden on mobile + mobileVisible?: boolean; + number?: number; + arrows?: boolean; + clickable?: boolean; + size?: Size; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/size.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/size.interface.ts new file mode 100644 index 00000000..9fea6b44 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/size.interface.ts @@ -0,0 +1,32 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +/** + * Interface `Size` to configure the size based on width and height. + * They can be pixels, percentages or also 'auto'. + */ +export interface Size { + width: string; + height: string; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/model/slide-config.interface.ts b/projects/ks89/angular-modal-gallery/src/lib/model/slide-config.interface.ts new file mode 100644 index 00000000..d29edef2 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/model/slide-config.interface.ts @@ -0,0 +1,43 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Size } from './size.interface'; +import { PlayConfig } from './play-config.interface'; + +/** + * Interface `SlideConfig` to configure sliding features of modal gallery. + */ +export interface SlideConfig { + infinite?: boolean; + playConfig?: PlayConfig; + sidePreviews?: SidePreviewsConfig; +} + +/** + * Interface `SidePreviewsConfig` to configure sliding features of previews in modal gallery. + */ +export interface SidePreviewsConfig { + show: boolean; + size: Size; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/services/config.service.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/services/config.service.spec.ts new file mode 100644 index 00000000..09ed1cae --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/services/config.service.spec.ts @@ -0,0 +1,838 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { inject, TestBed, waitForAsync } from '@angular/core/testing'; + +import { + ConfigService, + DEFAULT_CAROUSEL_BREAKPOINTS, + DEFAULT_CAROUSEL_DESCRIPTION, + DEFAULT_CAROUSEL_IMAGE_CONFIG, + DEFAULT_CAROUSEL_PREVIEWS_CONFIG, + DEFAULT_CURRENT_CAROUSEL_CONFIG, + DEFAULT_CURRENT_CAROUSEL_PLAY, + DEFAULT_CURRENT_IMAGE_CONFIG, + DEFAULT_DESCRIPTION, + DEFAULT_DESCRIPTION_STYLE, + DEFAULT_LAYOUT, + DEFAULT_LOADING, + DEFAULT_PLAIN_CONFIG, + DEFAULT_PREVIEW_CONFIG, + DEFAULT_PREVIEW_SIZE, + DEFAULT_SLIDE_CONFIG +} from './config.service'; +import { LibConfig } from '../model/lib-config.interface'; +import { ButtonsConfig, ButtonsStrategy, ButtonType } from '../model/buttons-config.interface'; +import { AccessibilityConfig } from '../model/accessibility.interface'; +import { KS_DEFAULT_ACCESSIBILITY_CONFIG } from '../components/accessibility-default'; +import { Size } from '../model/size.interface'; +import { DotsConfig } from '../model/dots-config.interface'; +import { KeyboardConfig } from '../model/keyboard-config.interface'; +import { CarouselConfig } from '../model/carousel-config.interface'; +import { PlayConfig } from '../model/play-config.interface'; +import { CarouselPreviewConfig } from '../model/carousel-preview-config.interface'; +import { CarouselImageConfig } from '../model/carousel-image-config.interface'; +import { Description, DescriptionStrategy, DescriptionStyle } from '../model/description.interface'; +import { AdvancedConfig, GridLayout, LineLayout, PlainGalleryConfig, PlainGalleryStrategy } from '../model/plain-gallery-config.interface'; +import { CurrentImageConfig } from '../model/current-image-config.interface'; +import { LoadingConfig, LoadingType } from '../model/loading-config.interface'; +import { SidePreviewsConfig, SlideConfig } from '../model/slide-config.interface'; +import { PreviewConfig } from '../model/preview-config.interface'; + +// tslint:disable:no-shadowed-variable + +describe('ConfigService', () => { + + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + providers: [ConfigService] + }); + }) + ); + + it('should instantiate service when inject service', + inject([ConfigService], (service: ConfigService) => { + expect(service instanceof ConfigService).toEqual(true); + }) + ); + + describe('#setConfig()', () => { + + describe('---YES---', () => { + + describe('slideConfig', () => { + + it(`should call setConfig to update the library configuration with an undefined slideConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + slideConfig: undefined + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.slideConfig).toEqual(DEFAULT_SLIDE_CONFIG); + }) + ); + + it(`should call setConfig to update the library configuration with a custom slideConfig (playConfig and sidePreviews are undefined)`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + slideConfig: { + infinite: true, + playConfig: undefined, + sidePreviews: undefined + } as SlideConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.slideConfig?.infinite).toEqual(inputConfig.slideConfig?.infinite); + expect(result?.slideConfig?.playConfig).toEqual({autoPlay: false, interval: 5000, pauseOnHover: true} as PlayConfig); + expect(result?.slideConfig?.sidePreviews).toEqual({show: true, size: {width: '100px', height: 'auto'}} as SidePreviewsConfig); + }) + ); + + it(`should call setConfig to update the library configuration with a custom slideConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + slideConfig: { + infinite: true, + playConfig: {autoPlay: true, interval: 10000, pauseOnHover: false} as PlayConfig, + sidePreviews: {show: false, size: {width: '200px', height: '100px'}} as SidePreviewsConfig + } as SlideConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.slideConfig?.infinite).toEqual(inputConfig.slideConfig?.infinite); + expect(result?.slideConfig?.playConfig?.autoPlay).toEqual(inputConfig.slideConfig?.playConfig?.autoPlay); + expect(result?.slideConfig?.playConfig?.interval).toEqual(inputConfig.slideConfig?.playConfig?.interval); + expect(result?.slideConfig?.playConfig?.pauseOnHover).toEqual(inputConfig.slideConfig?.playConfig?.pauseOnHover); + expect(result?.slideConfig?.sidePreviews?.show).toEqual(inputConfig.slideConfig?.sidePreviews?.show); + expect(result?.slideConfig?.sidePreviews?.size?.width).toEqual(inputConfig.slideConfig?.sidePreviews?.size?.width); + expect(result?.slideConfig?.sidePreviews?.size?.height).toEqual(inputConfig.slideConfig?.sidePreviews?.size?.height); + }) + ); + }); + + describe('accessibilityConfig', () => { + it(`should call setConfig to update the library configuration with an undefined accessibilityConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + accessibilityConfig: undefined + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.accessibilityConfig).toEqual(KS_DEFAULT_ACCESSIBILITY_CONFIG); + }) + ); + + it(`should call setConfig to update the library configuration with a custom accessibilityConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + accessibilityConfig: { + backgroundAriaLabel: 'example-test' + } as AccessibilityConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + if (!result || !result.accessibilityConfig || !inputConfig || !inputConfig.accessibilityConfig) { + throw new Error('Interrupted test, because of some undefined values'); + } + expect(result.accessibilityConfig.backgroundAriaLabel).toEqual(inputConfig.accessibilityConfig.backgroundAriaLabel); + }) + ); + }); + + describe('previewConfig', () => { + + it(`should call setConfig to update the library configuration with an undefined previewConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + previewConfig: undefined + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.previewConfig).toEqual(DEFAULT_PREVIEW_CONFIG); + }) + ); + + it(`should call setConfig to update the library configuration with a custom previewConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + previewConfig: { + visible: false, + number: 2, + arrows: false, + clickable: false, + size: DEFAULT_PREVIEW_SIZE + } as PreviewConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.previewConfig?.visible).toEqual(inputConfig.previewConfig?.visible); + expect(result?.previewConfig?.number).toEqual(inputConfig.previewConfig?.number); + expect(result?.previewConfig?.arrows).toEqual(inputConfig.previewConfig?.arrows); + expect(result?.previewConfig?.clickable).toEqual(inputConfig.previewConfig?.clickable); + expect(result?.previewConfig?.size).toEqual(inputConfig.previewConfig?.size); + }) + ); + + it(`should call setConfig to update the library configuration with a custom previewConfig (number < 0)`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + previewConfig: { + visible: false, + number: -1, + arrows: false, + clickable: false, + size: DEFAULT_PREVIEW_SIZE + } as PreviewConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.previewConfig?.visible).toEqual(inputConfig.previewConfig?.visible); + expect(result?.previewConfig?.number).toEqual(DEFAULT_PREVIEW_CONFIG.number); + expect(result?.previewConfig?.arrows).toEqual(inputConfig.previewConfig?.arrows); + expect(result?.previewConfig?.clickable).toEqual(inputConfig.previewConfig?.clickable); + expect(result?.previewConfig?.size).toEqual(inputConfig.previewConfig?.size); + }) + ); + + it(`should call setConfig to update the library configuration with a custom previewConfig (number = 0)`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + previewConfig: { + visible: false, + number: 0, + arrows: false, + clickable: false, + size: DEFAULT_PREVIEW_SIZE + } as PreviewConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.previewConfig?.visible).toEqual(inputConfig.previewConfig?.visible); + expect(result?.previewConfig?.number).toEqual(DEFAULT_PREVIEW_CONFIG.number); + expect(result?.previewConfig?.arrows).toEqual(inputConfig.previewConfig?.arrows); + expect(result?.previewConfig?.clickable).toEqual(inputConfig.previewConfig?.clickable); + expect(result?.previewConfig?.size).toEqual(inputConfig.previewConfig?.size); + }) + ); + }); + + describe('buttonsConfig', () => { + it(`should call setConfig to update the library configuration with an undefined buttonsConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + buttonsConfig: undefined + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.buttonsConfig).toEqual({visible: true, strategy: ButtonsStrategy.DEFAULT}); + }) + ); + + it(`should call setConfig to update the library configuration with a custom buttonsConfig`, + inject([ConfigService], (service: ConfigService) => { + const customConfig: ButtonsConfig = { + visible: false, + strategy: ButtonsStrategy.CUSTOM, + buttons: [{ + className: 'fake', + size: {height: '100px', width: '200px'} as Size, + fontSize: '12px', + type: ButtonType.CUSTOM, + title: 'fake title', + ariaLabel: 'fake aria label', + extUrlInNewTab: false + }] + }; + const inputConfig: LibConfig = { + buttonsConfig: customConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.buttonsConfig?.visible).toEqual(inputConfig.buttonsConfig?.visible); + expect(result?.buttonsConfig?.strategy).toEqual(inputConfig.buttonsConfig?.strategy); + expect(result?.buttonsConfig?.buttons).toEqual(inputConfig.buttonsConfig?.buttons); + }) + ); + }); + + describe('dotsConfig', () => { + + it(`should call setConfig to update the library configuration with an undefined dotsConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + dotsConfig: undefined + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.dotsConfig).toEqual({visible: true} as DotsConfig); + }) + ); + + it(`should call setConfig to update the library configuration with a custom dotsConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + dotsConfig: {visible: false} as DotsConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.dotsConfig?.visible).toEqual(inputConfig.dotsConfig?.visible); + }) + ); + }); + + describe('plainGalleryConfig', () => { + + it(`should call setConfig to update the library configuration with an undefined plainGalleryConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + plainGalleryConfig: undefined + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.plainGalleryConfig).toEqual(DEFAULT_PLAIN_CONFIG); + }) + ); + + it(`should call setConfig to update the library configuration with a custom plainGalleryConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + plainGalleryConfig: { + strategy: PlainGalleryStrategy.ROW, + layout: DEFAULT_LAYOUT, + advanced: undefined + } as PlainGalleryConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.plainGalleryConfig?.strategy).toEqual(inputConfig.plainGalleryConfig?.strategy); + expect(result?.plainGalleryConfig?.layout).toEqual(inputConfig.plainGalleryConfig?.layout); + expect(result?.plainGalleryConfig?.advanced).toEqual({aTags: false, additionalBackground: '50% 50%/cover'} as AdvancedConfig); + }) + ); + + it(`should call setConfig to update the library configuration with a custom plainGalleryConfig with custom advanced`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + plainGalleryConfig: { + strategy: PlainGalleryStrategy.ROW, + layout: DEFAULT_LAYOUT, + advanced: {aTags: true, additionalBackground: '10% 10%/cover'} as AdvancedConfig + } as PlainGalleryConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.plainGalleryConfig?.strategy).toEqual(inputConfig.plainGalleryConfig?.strategy); + expect(result?.plainGalleryConfig?.layout).toEqual(inputConfig.plainGalleryConfig?.layout); + expect(result?.plainGalleryConfig?.advanced?.aTags).toEqual(inputConfig.plainGalleryConfig?.advanced?.aTags); + expect(result?.plainGalleryConfig?.advanced?.additionalBackground).toEqual(inputConfig.plainGalleryConfig?.advanced?.additionalBackground); + }) + ); + + it(`should call setConfig to update the library configuration with a custom plainGalleryConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + plainGalleryConfig: { + strategy: PlainGalleryStrategy.GRID, + layout: new GridLayout(DEFAULT_PREVIEW_SIZE, {length: -1, wrap: false}), + advanced: {aTags: true, additionalBackground: '10% 10%/cover'} as AdvancedConfig + } as PlainGalleryConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + // wrap is forced to true in case of GridLayout + expect((result?.plainGalleryConfig?.layout as GridLayout).breakConfig?.wrap).toEqual(true); + }) + ); + }); + + describe('currentImageConfig', () => { + it(`should call setConfig to update the library configuration with an undefined currentImageConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + currentImageConfig: undefined + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.currentImageConfig).toEqual(DEFAULT_CURRENT_IMAGE_CONFIG); + }) + ); + + it(`should call setConfig to update the library configuration with a custom currentImageConfig (loadingConfig and description are undefined)`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + currentImageConfig: { + navigateOnClick: false, + loadingConfig: undefined, + description: undefined, + downloadable: true, + invertSwipe: true + } as CurrentImageConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.currentImageConfig?.navigateOnClick).toEqual(inputConfig.currentImageConfig?.navigateOnClick); + expect(result?.currentImageConfig?.downloadable).toEqual(inputConfig.currentImageConfig?.downloadable); + expect(result?.currentImageConfig?.invertSwipe).toEqual(inputConfig.currentImageConfig?.invertSwipe); + expect(result?.currentImageConfig?.loadingConfig).toEqual(DEFAULT_LOADING); + expect(result?.currentImageConfig?.description).toEqual(DEFAULT_DESCRIPTION); + }) + ); + + it(`should call setConfig to update the library configuration with a custom currentImageConfig (custom loadingConfig)`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + currentImageConfig: { + navigateOnClick: false, + loadingConfig: {enable: false, type: LoadingType.CIRCLES} as LoadingConfig, + description: undefined, + downloadable: true, + invertSwipe: true + } as CurrentImageConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.currentImageConfig?.navigateOnClick).toEqual(inputConfig.currentImageConfig?.navigateOnClick); + expect(result?.currentImageConfig?.downloadable).toEqual(inputConfig.currentImageConfig?.downloadable); + expect(result?.currentImageConfig?.invertSwipe).toEqual(inputConfig.currentImageConfig?.invertSwipe); + expect(result?.currentImageConfig?.loadingConfig?.enable).toEqual(inputConfig.currentImageConfig?.loadingConfig?.enable); + expect(result?.currentImageConfig?.loadingConfig?.type).toEqual(inputConfig.currentImageConfig?.loadingConfig?.type); + expect(result?.currentImageConfig?.description).toEqual(DEFAULT_DESCRIPTION); + }) + ); + + it(`should call setConfig to update the library configuration with a custom currentImageConfig (custom description)`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + currentImageConfig: { + navigateOnClick: false, + loadingConfig: undefined, + description: { + strategy: DescriptionStrategy.HIDE_IF_EMPTY, + imageText: 'Img ', + numberSeparator: ' of ', + beforeTextDescription: ' * ', + style: DEFAULT_DESCRIPTION_STYLE + } as Description, + downloadable: true, + invertSwipe: true + } as CurrentImageConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.currentImageConfig?.navigateOnClick).toEqual(inputConfig.currentImageConfig?.navigateOnClick); + expect(result?.currentImageConfig?.downloadable).toEqual(inputConfig.currentImageConfig?.downloadable); + expect(result?.currentImageConfig?.invertSwipe).toEqual(inputConfig.currentImageConfig?.invertSwipe); + expect(result?.currentImageConfig?.loadingConfig).toEqual(DEFAULT_LOADING); + expect(result?.currentImageConfig?.description?.strategy).toEqual(inputConfig.currentImageConfig?.description?.strategy); + expect(result?.currentImageConfig?.description?.imageText).toEqual(inputConfig.currentImageConfig?.description?.imageText); + expect(result?.currentImageConfig?.description?.numberSeparator).toEqual(inputConfig.currentImageConfig?.description?.numberSeparator); + expect(result?.currentImageConfig?.description?.beforeTextDescription).toEqual(inputConfig.currentImageConfig?.description?.beforeTextDescription); + expect(result?.currentImageConfig?.description?.style).toEqual(inputConfig.currentImageConfig?.description?.style); + }) + ); + + it(`should call setConfig to update the library configuration with a custom currentImageConfig (custom description with style undefined)`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + currentImageConfig: { + navigateOnClick: false, + loadingConfig: undefined, + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + imageText: 'Img ', + numberSeparator: ' of ', + beforeTextDescription: ' * ', + style: undefined + } as Description, + downloadable: true, + invertSwipe: true + } as CurrentImageConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.currentImageConfig?.navigateOnClick).toEqual(inputConfig.currentImageConfig?.navigateOnClick); + expect(result?.currentImageConfig?.downloadable).toEqual(inputConfig.currentImageConfig?.downloadable); + expect(result?.currentImageConfig?.invertSwipe).toEqual(inputConfig.currentImageConfig?.invertSwipe); + expect(result?.currentImageConfig?.loadingConfig).toEqual(DEFAULT_LOADING); + expect(result?.currentImageConfig?.description?.strategy).toEqual(inputConfig.currentImageConfig?.description?.strategy); + expect(result?.currentImageConfig?.description?.imageText).toEqual(inputConfig.currentImageConfig?.description?.imageText); + expect(result?.currentImageConfig?.description?.numberSeparator).toEqual(inputConfig.currentImageConfig?.description?.numberSeparator); + expect(result?.currentImageConfig?.description?.beforeTextDescription).toEqual(inputConfig.currentImageConfig?.description?.beforeTextDescription); + expect(result?.currentImageConfig?.description?.style).toEqual(DEFAULT_DESCRIPTION_STYLE); + }) + ); + }); + + describe('keyboardConfig', () => { + + it(`should call setConfig to update the library configuration with an undefined keyboardConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + keyboardConfig: undefined + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.keyboardConfig).toEqual(undefined); + }) + ); + + it(`should call setConfig to update the library configuration with a custom keyboardConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + keyboardConfig: { + esc: 'KeyQ', + right: 'KeyW', + left: 'KeyE' + } as KeyboardConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.keyboardConfig).toEqual(inputConfig.keyboardConfig); + }) + ); + }); + + describe('carouselImageConfig', () => { + + it(`should call setConfig to update the library configuration with an undefined carouselImageConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + carouselImageConfig: undefined + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.carouselImageConfig).toEqual(DEFAULT_CAROUSEL_IMAGE_CONFIG); + }) + ); + + it(`should call setConfig to update the library configuration with a custom carouselImageConfig (description undefined)`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + carouselImageConfig: { + description: undefined, + invertSwipe: true + } as CarouselImageConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.carouselImageConfig?.invertSwipe).toEqual(inputConfig.carouselImageConfig?.invertSwipe); + expect(result?.carouselImageConfig?.description).toEqual(DEFAULT_CAROUSEL_DESCRIPTION); + }) + ); + + it(`should call setConfig to update the library configuration with a custom carouselImageConfig (description.style undefined)`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + carouselImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_HIDDEN, + imageText: 'Img ', + numberSeparator: ' of ', + beforeTextDescription: ' * ', + style: undefined + }, + invertSwipe: true + } as CarouselImageConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.carouselImageConfig?.invertSwipe).toEqual(inputConfig.carouselImageConfig?.invertSwipe); + expect(result?.carouselImageConfig?.description?.strategy).toEqual(inputConfig.carouselImageConfig?.description?.strategy); + expect(result?.carouselImageConfig?.description?.imageText).toEqual(inputConfig.carouselImageConfig?.description?.imageText); + expect(result?.carouselImageConfig?.description?.numberSeparator).toEqual(inputConfig.carouselImageConfig?.description?.numberSeparator); + expect(result?.carouselImageConfig?.description?.beforeTextDescription).toEqual(inputConfig.carouselImageConfig?.description?.beforeTextDescription); + expect(result?.carouselImageConfig?.description?.style).toEqual(DEFAULT_DESCRIPTION_STYLE); + }) + ); + + it(`should call setConfig to update the library configuration with a custom carouselImageConfig (custom description.style)`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + carouselImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_HIDDEN, + imageText: 'Img ', + numberSeparator: ' of ', + beforeTextDescription: ' * ', + style: { + bgColor: 'rgba(200, 0, 120, .5)', + textColor: 'black', + marginTop: '5px', + marginBottom: '10px', + marginLeft: '10px', + marginRight: '10px' + } as DescriptionStyle + }, + invertSwipe: true + } as CarouselImageConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.carouselImageConfig?.invertSwipe).toEqual(inputConfig.carouselImageConfig?.invertSwipe); + expect(result?.carouselImageConfig?.description?.strategy).toEqual(inputConfig.carouselImageConfig?.description?.strategy); + expect(result?.carouselImageConfig?.description?.imageText).toEqual(inputConfig.carouselImageConfig?.description?.imageText); + expect(result?.carouselImageConfig?.description?.numberSeparator).toEqual(inputConfig.carouselImageConfig?.description?.numberSeparator); + expect(result?.carouselImageConfig?.description?.beforeTextDescription).toEqual(inputConfig.carouselImageConfig?.description?.beforeTextDescription); + expect(result?.carouselImageConfig?.description?.style?.bgColor).toEqual(inputConfig.carouselImageConfig?.description?.style?.bgColor); + expect(result?.carouselImageConfig?.description?.style?.textColor).toEqual(inputConfig.carouselImageConfig?.description?.style?.textColor); + expect(result?.carouselImageConfig?.description?.style?.marginTop).toEqual(inputConfig.carouselImageConfig?.description?.style?.marginTop); + expect(result?.carouselImageConfig?.description?.style?.marginBottom).toEqual(inputConfig.carouselImageConfig?.description?.style?.marginBottom); + expect(result?.carouselImageConfig?.description?.style?.marginLeft).toEqual(inputConfig.carouselImageConfig?.description?.style?.marginLeft); + expect(result?.carouselImageConfig?.description?.style?.marginRight).toEqual(inputConfig.carouselImageConfig?.description?.style?.marginRight); + }) + ); + }); + + describe('carouselConfig', () => { + + it(`should call setConfig to update the library configuration with an undefined carouselConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + carouselConfig: undefined + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.carouselConfig).toEqual(DEFAULT_CURRENT_CAROUSEL_CONFIG); + }) + ); + + it(`should call setConfig to update the library configuration with a custom carouselConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + carouselConfig: { + maxWidth: '80%', + maxHeight: '200px', + showArrows: false, + objectFit: 'cover', + keyboardEnable: false, + modalGalleryEnable: false + } as CarouselConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.carouselConfig).toEqual(inputConfig.carouselConfig); + }) + ); + }); + + describe('carouselPlayConfig', () => { + + it(`should call setConfig to update the library configuration with an undefined carouselPlayConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + carouselPlayConfig: undefined + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.carouselPlayConfig).toEqual(DEFAULT_CURRENT_CAROUSEL_PLAY); + }) + ); + + it(`should call setConfig to update the library configuration with a custom carouselPlayConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + carouselPlayConfig: { + autoPlay: false, + interval: 1000, + pauseOnHover: false + } as PlayConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.carouselPlayConfig).toEqual(inputConfig.carouselPlayConfig); + }) + ); + }); + + describe('carouselPreviewsConfig', () => { + + it(`should call setConfig to update the library configuration with an undefined carouselPreviewsConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + carouselPreviewsConfig: undefined + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.carouselPreviewsConfig).toEqual(DEFAULT_CAROUSEL_PREVIEWS_CONFIG); + }) + ); + + it(`should call setConfig to update the library configuration with an undefined carouselPreviewsConfig without 'breakpoints'`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 4, + arrows: true, + clickable: true, + width: 100 / 4 + '%', + maxHeight: '200px' + } as CarouselPreviewConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.carouselPreviewsConfig).toEqual(DEFAULT_CAROUSEL_PREVIEWS_CONFIG); + }) + ); + + [0, -1].forEach((item: number, index: number) => { + it(`should call setConfig to update the library configuration with a custom carouselPreviewsConfig with invalid 'number'. Test i = ${index}`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + carouselPreviewsConfig: { + visible: false, + number: item, + arrows: false, + clickable: false, + width: 100 / 2 + '%', + maxHeight: '100px', + breakpoints: DEFAULT_CAROUSEL_BREAKPOINTS + } as CarouselPreviewConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + const numberVal: number = DEFAULT_CAROUSEL_PREVIEWS_CONFIG.number as number; + const widthVal: number = 100 / numberVal; + expect(result?.carouselPreviewsConfig?.visible).toEqual(inputConfig.carouselPreviewsConfig?.visible); + expect(result?.carouselPreviewsConfig?.number).toEqual(numberVal); + expect(result?.carouselPreviewsConfig?.arrows).toEqual(inputConfig.carouselPreviewsConfig?.arrows); + expect(result?.carouselPreviewsConfig?.clickable).toEqual(inputConfig.carouselPreviewsConfig?.clickable); + expect(result?.carouselPreviewsConfig?.width).toEqual(`${widthVal}%`); + expect(result?.carouselPreviewsConfig?.maxHeight).toEqual(inputConfig.carouselPreviewsConfig?.maxHeight); + expect(result?.carouselPreviewsConfig?.breakpoints).toEqual(inputConfig.carouselPreviewsConfig?.breakpoints); + }) + ); + }); + }); + + describe('carouselDotsConfig', () => { + + it(`should call setConfig to update the library configuration with an undefined carouselDotsConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + carouselDotsConfig: undefined + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.carouselDotsConfig).toEqual({visible: true} as DotsConfig); + }) + ); + + it(`should call setConfig to update the library configuration with a custom carouselDotsConfig`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + carouselDotsConfig: {visible: false} as DotsConfig + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.carouselDotsConfig).toEqual(inputConfig.carouselDotsConfig); + }) + ); + }); + + describe('enableCloseOutside', () => { + + it(`should call setConfig to update the library configuration with an undefined enableCloseOutside`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + enableCloseOutside: undefined + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.enableCloseOutside).toEqual(true); + }) + ); + + it(`should call setConfig to update the library configuration with a custom enableCloseOutside`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + enableCloseOutside: false + }; + service.setConfig(1, inputConfig); + const result: LibConfig | undefined = service.getConfig(1); + expect(result?.enableCloseOutside).toEqual(inputConfig.enableCloseOutside); + }) + ); + }); + + it(`should call setConfig with an undefined configuration object.`, + inject([ConfigService], (service: ConfigService) => { + service.setConfig(1, undefined); + const result: LibConfig | undefined = service.getConfig(1); + // console.log('result', result); + }) + ); + }); + + describe('---NO---', () => { + describe('carouselPlayConfig', () => { + it(`should throw an error if carouselPlayConfig.interval is < 0`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + carouselPlayConfig: { + autoPlay: false, + interval: -1, + pauseOnHover: false + } as PlayConfig + }; + expect(() => service.setConfig(1, inputConfig)).toThrowError(`Carousel's interval must be a number >= 0`); + }) + ); + }); + + describe('plainGalleryConfig', () => { + [PlainGalleryStrategy.GRID, PlainGalleryStrategy.CUSTOM].forEach((item: PlainGalleryStrategy) => { + it(`should throw an error because 'LineLayout requires either ROW or COLUMN strategy'`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + plainGalleryConfig: { + strategy: item, + layout: new LineLayout(DEFAULT_PREVIEW_SIZE, {length: -1, wrap: false}, 'flex-start'), + advanced: {aTags: true, additionalBackground: '10% 10%/cover'} as AdvancedConfig + } as PlainGalleryConfig + }; + expect(() => service.setConfig(1, inputConfig)).toThrowError('LineLayout requires either ROW or COLUMN strategy'); + }) + ); + }); + + it(`should throw an error because 'GridLayout requires GRID strategy'`, + inject([ConfigService], (service: ConfigService) => { + const inputConfig: LibConfig = { + plainGalleryConfig: { + strategy: PlainGalleryStrategy.ROW, + layout: new GridLayout(DEFAULT_PREVIEW_SIZE, {length: -1, wrap: false}), + advanced: {aTags: true, additionalBackground: '10% 10%/cover'} as AdvancedConfig + } as PlainGalleryConfig + }; + expect(() => service.setConfig(1, inputConfig)).toThrowError('GridLayout requires GRID strategy'); + }) + ); + }); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/services/config.service.ts b/projects/ks89/angular-modal-gallery/src/lib/services/config.service.ts new file mode 100644 index 00000000..6f6ec7ed --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/services/config.service.ts @@ -0,0 +1,388 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Injectable } from '@angular/core'; +import { SidePreviewsConfig, SlideConfig } from '../model/slide-config.interface'; +import { PlayConfig } from '../model/play-config.interface'; +import { KS_DEFAULT_ACCESSIBILITY_CONFIG } from '../components/accessibility-default'; +import { PreviewConfig } from '../model/preview-config.interface'; +import { Size } from '../model/size.interface'; +import { ButtonsConfig, ButtonsStrategy } from '../model/buttons-config.interface'; +import { DotsConfig } from '../model/dots-config.interface'; +import { GridLayout, LineLayout, PlainGalleryConfig, PlainGalleryStrategy } from '../model/plain-gallery-config.interface'; +import { CurrentImageConfig } from '../model/current-image-config.interface'; +import { LoadingConfig, LoadingType } from '../model/loading-config.interface'; +import { Description, DescriptionStrategy, DescriptionStyle } from '../model/description.interface'; +import { CarouselConfig } from '../model/carousel-config.interface'; +import { CarouselImageConfig } from '../model/carousel-image-config.interface'; +import { BreakpointsConfig, CarouselPreviewConfig } from '../model/carousel-preview-config.interface'; +import { LibConfig } from '../model/lib-config.interface'; + +export const DEFAULT_PREVIEW_SIZE: Size = { height: '50px', width: 'auto' }; +export const DEFAULT_LAYOUT: LineLayout = new LineLayout(DEFAULT_PREVIEW_SIZE, { length: -1, wrap: false }, 'flex-start'); +export const DEFAULT_PLAIN_CONFIG: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.ROW, + layout: DEFAULT_LAYOUT, + advanced: { aTags: false, additionalBackground: '50% 50%/cover' } +}; +export const DEFAULT_LOADING: LoadingConfig = { enable: true, type: LoadingType.STANDARD }; +export const DEFAULT_DESCRIPTION_STYLE: DescriptionStyle = { + bgColor: 'rgba(0, 0, 0, .5)', + textColor: 'white', + marginTop: '0px', + marginBottom: '0px', + marginLeft: '0px', + marginRight: '0px' +}; +export const DEFAULT_DESCRIPTION: Description = { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + imageText: 'Image ', + numberSeparator: '/', + beforeTextDescription: ' - ', + style: DEFAULT_DESCRIPTION_STYLE +}; +export const DEFAULT_CAROUSEL_DESCRIPTION: Description = { + strategy: DescriptionStrategy.ALWAYS_HIDDEN, + imageText: 'Image ', + numberSeparator: '/', + beforeTextDescription: ' - ', + style: DEFAULT_DESCRIPTION_STYLE +}; +export const DEFAULT_CURRENT_IMAGE_CONFIG: CurrentImageConfig = { + navigateOnClick: true, + loadingConfig: DEFAULT_LOADING, + description: DEFAULT_DESCRIPTION, + downloadable: false, + invertSwipe: false +}; +export const DEFAULT_CAROUSEL_IMAGE_CONFIG: CarouselImageConfig = { + description: DEFAULT_CAROUSEL_DESCRIPTION, + invertSwipe: false +}; +export const DEFAULT_CURRENT_CAROUSEL_CONFIG: CarouselConfig = { + maxWidth: '100%', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false +}; +export const DEFAULT_CURRENT_CAROUSEL_PLAY: PlayConfig = { + autoPlay: true, + interval: 5000, + pauseOnHover: true +}; + +export const DEFAULT_CAROUSEL_BREAKPOINTS: BreakpointsConfig = { xSmall: 100, small: 100, medium: 150, large: 200, xLarge: 200 }; +export const DEFAULT_CAROUSEL_PREVIEWS_CONFIG: CarouselPreviewConfig = { + visible: true, + number: 4, + arrows: true, + clickable: true, + width: 100 / 4 + '%', + maxHeight: '200px', + breakpoints: DEFAULT_CAROUSEL_BREAKPOINTS +}; +export const DEFAULT_SLIDE_CONFIG: SlideConfig = { + infinite: false, + playConfig: { autoPlay: false, interval: 5000, pauseOnHover: true } as PlayConfig, + sidePreviews: { show: true, size: { width: '100px', height: 'auto' } } as SidePreviewsConfig +}; +export const DEFAULT_PREVIEW_CONFIG: PreviewConfig = { + visible: true, + number: 3, + arrows: true, + clickable: true, + size: DEFAULT_PREVIEW_SIZE +}; + +const DEFAULT_CONFIG: LibConfig = Object.freeze({ + slideConfig: DEFAULT_SLIDE_CONFIG, + accessibilityConfig: KS_DEFAULT_ACCESSIBILITY_CONFIG, + previewConfig: DEFAULT_PREVIEW_CONFIG, + buttonsConfig: { visible: true, strategy: ButtonsStrategy.DEFAULT } as ButtonsConfig, + dotsConfig: { visible: true } as DotsConfig, + plainGalleryConfig: DEFAULT_PLAIN_CONFIG, + currentImageConfig: DEFAULT_CURRENT_IMAGE_CONFIG, + keyboardConfig: undefined, // by default nothing, because the library uses default buttons automatically + carouselConfig: DEFAULT_CURRENT_CAROUSEL_CONFIG, + carouselImageConfig: DEFAULT_CAROUSEL_IMAGE_CONFIG, + carouselPreviewsConfig: DEFAULT_CAROUSEL_PREVIEWS_CONFIG, + carouselPlayConfig: DEFAULT_CURRENT_CAROUSEL_PLAY, + carouselDotsConfig: { visible: true } as DotsConfig, + carouselSlideInfinite: true, + enableCloseOutside: true +}); + +/** + * Service to handle library configuration in a unique place + */ +@Injectable({ providedIn: 'root' }) +export class ConfigService { + configMap: Map = new Map(); + + getConfig(id: number): LibConfig | undefined { + this.initIfNotExists(id); + return this.configMap.get(id); + } + + setConfig(id: number, obj: LibConfig | undefined): void { + this.initIfNotExists(id); + if (!obj) { + return; + } + + if ( + !DEFAULT_CONFIG || + !DEFAULT_CONFIG.slideConfig || + !DEFAULT_CONFIG.slideConfig.sidePreviews || + !DEFAULT_CONFIG.previewConfig || + !DEFAULT_CONFIG.previewConfig.size || + !DEFAULT_CONFIG.previewConfig.number || + !DEFAULT_CONFIG.plainGalleryConfig || + !DEFAULT_CONFIG.currentImageConfig || + !DEFAULT_CONFIG.currentImageConfig || + !DEFAULT_CONFIG.currentImageConfig.description || + !DEFAULT_CONFIG.carouselImageConfig || + !DEFAULT_CONFIG.carouselImageConfig.description || + !DEFAULT_CONFIG.carouselPreviewsConfig || + !DEFAULT_CONFIG.carouselPreviewsConfig.breakpoints || + !DEFAULT_CAROUSEL_PREVIEWS_CONFIG.number + ) { + throw new Error('Internal library error - DEFAULT_CONFIG must be fully initialized!!!'); + } + + const newConfig: LibConfig = Object.assign({}, this.configMap.get(id)); + if (obj.slideConfig) { + let playConfig; + let sidePreviews; + let size; + if (obj.slideConfig.playConfig) { + playConfig = Object.assign({}, DEFAULT_CONFIG.slideConfig.playConfig, obj.slideConfig.playConfig); + } else { + playConfig = DEFAULT_CONFIG.slideConfig.playConfig; + } + if (obj.slideConfig.sidePreviews) { + if (obj.slideConfig.sidePreviews.size) { + size = Object.assign({}, DEFAULT_CONFIG.slideConfig.sidePreviews.size, obj.slideConfig.sidePreviews.size); + } else { + size = DEFAULT_CONFIG.slideConfig.sidePreviews.size; + } + sidePreviews = Object.assign({}, DEFAULT_CONFIG.slideConfig.sidePreviews, obj.slideConfig.sidePreviews); + } else { + sidePreviews = DEFAULT_CONFIG.slideConfig.sidePreviews; + size = DEFAULT_CONFIG.slideConfig.sidePreviews.size; + } + const newSlideConfig: SlideConfig = Object.assign({}, DEFAULT_CONFIG.slideConfig, obj.slideConfig); + newSlideConfig.playConfig = playConfig; + newSlideConfig.sidePreviews = sidePreviews; + newSlideConfig.sidePreviews.size = size; + newConfig.slideConfig = newSlideConfig; + } + if (obj.accessibilityConfig) { + newConfig.accessibilityConfig = Object.assign({}, DEFAULT_CONFIG.accessibilityConfig, obj.accessibilityConfig); + } + if (obj.previewConfig) { + let size: Size; + let num: number; + if (obj.previewConfig.size) { + size = Object.assign({}, DEFAULT_CONFIG.previewConfig.size, obj.previewConfig.size); + } else { + size = DEFAULT_CONFIG.previewConfig.size; + } + if (obj.previewConfig.number) { + if (obj.previewConfig.number <= 0) { + // if number is <= 0 reset to default + num = DEFAULT_CONFIG.previewConfig.number; + } else { + num = obj.previewConfig.number; + } + } else { + num = DEFAULT_CONFIG.previewConfig.number; + } + const newPreviewConfig: PreviewConfig = Object.assign({}, DEFAULT_CONFIG.previewConfig, obj.previewConfig); + newPreviewConfig.size = size; + newPreviewConfig.number = num; + newConfig.previewConfig = newPreviewConfig; + } + if (obj.buttonsConfig) { + newConfig.buttonsConfig = Object.assign({}, DEFAULT_CONFIG.buttonsConfig, obj.buttonsConfig); + } + if (obj.dotsConfig) { + newConfig.dotsConfig = Object.assign({}, DEFAULT_CONFIG.dotsConfig, obj.dotsConfig); + } + if (obj.plainGalleryConfig) { + let advanced; + let layout; + if (obj.plainGalleryConfig.advanced) { + advanced = Object.assign({}, DEFAULT_CONFIG.plainGalleryConfig.advanced, obj.plainGalleryConfig.advanced); + } else { + advanced = DEFAULT_CONFIG.plainGalleryConfig.advanced; + } + if (obj.plainGalleryConfig.layout) { + // it isn't mandatory to use assign, because obj.plainGalleryConfig.layout is an instance of class (LineaLayout, GridLayout) + layout = obj.plainGalleryConfig.layout; + } else { + layout = DEFAULT_CONFIG.plainGalleryConfig.layout; + } + const newPlainGalleryConfig: PlainGalleryConfig = Object.assign({}, DEFAULT_CONFIG.plainGalleryConfig, obj.plainGalleryConfig); + newPlainGalleryConfig.layout = layout; + newPlainGalleryConfig.advanced = advanced; + newConfig.plainGalleryConfig = initPlainGalleryConfig(newPlainGalleryConfig); + } + if (obj.currentImageConfig) { + let loading; + let description; + let descriptionStyle; + if (obj.currentImageConfig.loadingConfig) { + loading = Object.assign({}, DEFAULT_CONFIG.currentImageConfig.loadingConfig, obj.currentImageConfig.loadingConfig); + } else { + loading = DEFAULT_CONFIG.currentImageConfig.loadingConfig; + } + if (obj.currentImageConfig.description) { + description = Object.assign({}, DEFAULT_CONFIG.currentImageConfig.description, obj.currentImageConfig.description); + if (obj.currentImageConfig.description.style) { + descriptionStyle = Object.assign({}, DEFAULT_CONFIG.currentImageConfig.description.style, obj.currentImageConfig.description.style); + } else { + descriptionStyle = DEFAULT_CONFIG.currentImageConfig.description.style; + } + } else { + description = DEFAULT_CONFIG.currentImageConfig.description; + descriptionStyle = DEFAULT_CONFIG.currentImageConfig.description.style; + } + const newCurrentImageConfig: CurrentImageConfig = Object.assign({}, DEFAULT_CONFIG.currentImageConfig, obj.currentImageConfig); + newCurrentImageConfig.loadingConfig = loading; + newCurrentImageConfig.description = description; + newCurrentImageConfig.description.style = descriptionStyle; + newConfig.currentImageConfig = newCurrentImageConfig; + } + if (obj.keyboardConfig) { + newConfig.keyboardConfig = Object.assign({}, DEFAULT_CONFIG.keyboardConfig, obj.keyboardConfig); + } + + // carousel + if (obj.carouselConfig) { + newConfig.carouselConfig = Object.assign({}, DEFAULT_CONFIG.carouselConfig, obj.carouselConfig); + } + if (obj.carouselImageConfig) { + let description; + let descriptionStyle; + if (obj.carouselImageConfig.description) { + description = Object.assign({}, DEFAULT_CONFIG.carouselImageConfig.description, obj.carouselImageConfig.description); + if (obj.carouselImageConfig.description.style) { + descriptionStyle = Object.assign({}, DEFAULT_CONFIG.carouselImageConfig.description.style, obj.carouselImageConfig.description.style); + } else { + descriptionStyle = DEFAULT_CONFIG.carouselImageConfig.description.style; + } + } else { + description = DEFAULT_CONFIG.carouselImageConfig.description; + descriptionStyle = DEFAULT_CONFIG.carouselImageConfig.description.style; + } + const newCarouselImageConfig: CarouselImageConfig = Object.assign({}, DEFAULT_CONFIG.carouselImageConfig, obj.carouselImageConfig); + newCarouselImageConfig.description = description; + newCarouselImageConfig.description.style = descriptionStyle; + newConfig.carouselImageConfig = newCarouselImageConfig; + } + if (obj.carouselPlayConfig) { + // check values + if (obj.carouselPlayConfig.interval <= 0) { + throw new Error(`Carousel's interval must be a number >= 0`); + } + newConfig.carouselPlayConfig = Object.assign({}, DEFAULT_CONFIG.carouselPlayConfig, obj.carouselPlayConfig); + } + if (obj.carouselPreviewsConfig) { + // check values + let num: number; + let breakpoints: BreakpointsConfig; + if (!obj.carouselPreviewsConfig.number || obj.carouselPreviewsConfig.number <= 0) { + num = DEFAULT_CAROUSEL_PREVIEWS_CONFIG.number; + } else { + num = obj.carouselPreviewsConfig.number; + } + if (obj.carouselPreviewsConfig.breakpoints) { + breakpoints = Object.assign({}, DEFAULT_CONFIG.carouselPreviewsConfig.breakpoints, obj.carouselPreviewsConfig.breakpoints); + } else { + breakpoints = DEFAULT_CONFIG.carouselPreviewsConfig.breakpoints; + } + newConfig.carouselPreviewsConfig = Object.assign({}, DEFAULT_CONFIG.carouselPreviewsConfig, obj.carouselPreviewsConfig); + newConfig.carouselPreviewsConfig.number = num; + newConfig.carouselPreviewsConfig.breakpoints = breakpoints; + // Init preview image width based on the number of previews in PreviewConfig + // Don't move this line above, because I need to be sure that both configPreview.number + // and configPreview.size are initialized + newConfig.carouselPreviewsConfig.width = 100 / newConfig.carouselPreviewsConfig.number + '%'; + } + if (obj.carouselDotsConfig) { + newConfig.carouselDotsConfig = Object.assign({}, DEFAULT_CONFIG.carouselDotsConfig, obj.carouselDotsConfig); + } + if (obj.carouselSlideInfinite === undefined) { + newConfig.carouselSlideInfinite = DEFAULT_CONFIG.carouselSlideInfinite; + } else { + newConfig.carouselSlideInfinite = obj.carouselSlideInfinite; + } + if (obj.enableCloseOutside === undefined) { + newConfig.enableCloseOutside = DEFAULT_CONFIG.enableCloseOutside; + } else { + newConfig.enableCloseOutside = obj.enableCloseOutside; + } + this.configMap.set(id, newConfig); + } + + private initIfNotExists(id: number): void { + if (!this.configMap.has(id)) { + this.configMap.set(id, DEFAULT_CONFIG); + } + } +} + +/** + * Function to build and return a `PlainGalleryConfig` object, proving also default values and validating the input object. + * @param plainGalleryConfig object with the config requested by user + * @returns PlainGalleryConfig the plain gallery configuration + * @throws an Error if layout and strategy aren't compatible + */ +function initPlainGalleryConfig(plainGalleryConfig: PlainGalleryConfig): PlainGalleryConfig { + const newPlayGalleryConfig: PlainGalleryConfig = Object.assign({}, DEFAULT_CONFIG.plainGalleryConfig, plainGalleryConfig); + + if (newPlayGalleryConfig.layout instanceof LineLayout) { + if (newPlayGalleryConfig.strategy !== PlainGalleryStrategy.ROW && newPlayGalleryConfig.strategy !== PlainGalleryStrategy.COLUMN) { + throw new Error('LineLayout requires either ROW or COLUMN strategy'); + } + if (!newPlayGalleryConfig.layout || !newPlayGalleryConfig.layout.breakConfig) { + throw new Error('Both layout and breakConfig must be valid'); + } + } + + if (newPlayGalleryConfig.layout instanceof GridLayout) { + if (newPlayGalleryConfig.strategy !== PlainGalleryStrategy.GRID) { + throw new Error('GridLayout requires GRID strategy'); + } + if (!newPlayGalleryConfig.layout || !newPlayGalleryConfig.layout.breakConfig) { + throw new Error('Both layout and breakConfig must be valid'); + } + // force wrap for grid layout + newPlayGalleryConfig.layout.breakConfig.wrap = true; + } + return newPlayGalleryConfig; +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/services/id-validator.service.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/services/id-validator.service.spec.ts new file mode 100644 index 00000000..eee0016e --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/services/id-validator.service.spec.ts @@ -0,0 +1,133 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { inject, TestBed, waitForAsync } from '@angular/core/testing'; + +import { IdValidatorService } from './id-validator.service'; + +const validIds: number[] = [0, 1, 2, 3, 500, 900, 1000]; +const notValidIds: number[] = [-12, -50, -1, NaN]; + +const errorMessage = 'You must provide a valid [id]="unique integer > 0 here" to the gallery/carousel in your template'; + +function getErrorNotUnique(galleryId: number): string { + return `Cannot create gallery with id=${galleryId} because already used in your application. This must be a unique integer >= 0`; +} + +describe('IdValidatorService', () => { + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + providers: [IdValidatorService] + }); + }) + ); + + it('should instantiate service when inject service', + inject([IdValidatorService], (service: IdValidatorService) => { + expect(service instanceof IdValidatorService).toEqual(true); + }) + ); + + describe('#checkAndAdd()', () => { + validIds.forEach((val: number, index: number) => { + it(`should call checkAndAdd with valid inputs expecting true as result. Test i=${index}`, + inject([IdValidatorService], (service: IdValidatorService) => { + expect(service.checkAndAdd(val)).toBeTruthy(); + }) + ); + }); + + notValidIds.forEach((val: number, index: number) => { + it(`should call checkAndAdd with bad inputs expecting an error as result. Test i=${index}`, + inject([IdValidatorService], (service: IdValidatorService) => { + expect(() => service.checkAndAdd(val)).toThrow(new Error(errorMessage)); + }) + ); + }); + + it(`should call checkAndAdd multiple times with the same input expecting an error as result.`, + inject([IdValidatorService], (service: IdValidatorService) => { + const multipleValue = 5; + service.checkAndAdd(0); + service.checkAndAdd(1); + service.checkAndAdd(multipleValue); + service.checkAndAdd(300); + expect(() => service.checkAndAdd(multipleValue)).toThrow(new Error(getErrorNotUnique(multipleValue))); + }) + ); + }); + + describe('#remove()', () => { + validIds.forEach((val: number, index: number) => { + it(`should call remove with valid inputs expecting true as result. Test i=${index}`, + inject([IdValidatorService], (service: IdValidatorService) => { + expect(service.remove(val)).toBeTruthy(); + }) + ); + }); + + it(`should call remove multiple times with the same input expecting true as result.`, + inject([IdValidatorService], (service: IdValidatorService) => { + const multipleValue = 5; + service.checkAndAdd(0); + service.checkAndAdd(1); + service.checkAndAdd(multipleValue); + expect(service.remove(multipleValue)).toBeTruthy(); + expect(service.remove(multipleValue)).toBeTruthy(); + }) + ); + + it(`should call remove for a non existing id expecting true as result.`, + inject([IdValidatorService], (service: IdValidatorService) => { + const notExisting = 5; + service.checkAndAdd(0); + service.checkAndAdd(1); + expect(service.remove(notExisting)).toBeTruthy(); + expect(service.remove(notExisting)).toBeTruthy(); + }) + ); + + it(`should call remove for an id and add it again without errors.`, + inject([IdValidatorService], (service: IdValidatorService) => { + const validId = 5; + service.checkAndAdd(0); + service.checkAndAdd(1); + service.checkAndAdd(validId); + expect(service.remove(validId)).toBeTruthy(); + expect(service.checkAndAdd(validId)).toBeTruthy(); + expect(service.remove(validId)).toBeTruthy(); + expect(service.checkAndAdd(validId)).toBeTruthy(); + }) + ); + + notValidIds.forEach((val: number, index: number) => { + it(`should call remove with bad inputs expecting an error as result. Test i=${index}`, + inject([IdValidatorService], (service: IdValidatorService) => { + expect(() => service.remove(val)).toThrow(new Error(errorMessage)); + }) + ); + }); + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/services/id-validator.service.ts b/projects/ks89/angular-modal-gallery/src/lib/services/id-validator.service.ts new file mode 100644 index 00000000..29b92f95 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/services/id-validator.service.ts @@ -0,0 +1,66 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Injectable } from '@angular/core'; + +/** + * Service to check if the provided id is unique + */ +@Injectable({ providedIn: 'root' }) +export class IdValidatorService { + ids = new Map(); + + /** + * Method to check and reserve an id for the current instance of the library. + * In this way, no other instances can use the same id. + * @param galleryId number or undefined that represents the unique id of the gallery. + * @return boolean true if success. false is never returned, instead an exception is thrown + * @throws a error with a message if galleryId is neither unique, < 0 or an integer + */ + checkAndAdd(galleryId: number | undefined): boolean { + if (galleryId === undefined || !Number.isInteger(galleryId) || galleryId < 0) { + throw new Error('You must provide a valid [id]="unique integer > 0 here" to the gallery/carousel in your template'); + } + if (this.ids.get(galleryId)) { + throw new Error(`Cannot create gallery with id=${galleryId} because already used in your application. This must be a unique integer >= 0`); + } + this.ids.set(galleryId, galleryId); + return true; + } + + /** + * Method to remove a reserved id. In this way you are able to use the id again for another instance of the library. + * @param galleryId number or undefined that represents the unique id of the gallery. + * @return boolean true if success. false is never returned, instead an exception is thrown* + * @throws a error with a message if galleryId is neither integer or < 0 + * * this should be improved without return true, because it doesn't make sense! :( + */ + remove(galleryId: number | undefined): boolean { + if (galleryId === undefined || !Number.isInteger(galleryId) || galleryId < 0) { + throw new Error('You must provide a valid [id]="unique integer > 0 here" to the gallery/carousel in your template'); + } + this.ids.delete(galleryId); + return true; + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/utils/breakpoint-observer-mock.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/utils/breakpoint-observer-mock.spec.ts new file mode 100644 index 00000000..66e77a41 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/utils/breakpoint-observer-mock.spec.ts @@ -0,0 +1,23 @@ +import { Injectable } from '@angular/core'; +import { Observable, of } from 'rxjs'; +import { Breakpoints, BreakpointState } from '@angular/cdk/layout'; + +/** + * Mocked BreakpointObserver service from @angular/cdk used only in testing + */ +@Injectable({providedIn: 'root'}) +export class MediumMockedBreakpointObserver { + isMatched(value: string | string[]): boolean { + return value === Breakpoints.Medium; + } + + observe(value: string | string[]): Observable { + const response: BreakpointState = { + matches: false, + breakpoints: { + Medium: true + } + }; + return of(response); + } +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/utils/image.util.spec.ts b/projects/ks89/angular-modal-gallery/src/lib/utils/image.util.spec.ts new file mode 100644 index 00000000..a00f5f22 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/utils/image.util.spec.ts @@ -0,0 +1,109 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Image } from '../model/image.class'; +import { getIndex } from './image.util'; + +const imagesMock: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg' + }), + new Image(2, { + img: '../assets/images/gallery/img2.jpg' + }), + new Image(1, { + img: '../assets/images/gallery/img3.jpg' + }), + new Image(3, { + img: '../assets/images/gallery/img4.jpg' + }) +]; + +const imagesMockEqualIds: Image[] = [ + new Image(1, { + img: '../assets/images/gallery/img1.jpg' + }), + new Image(1, { + img: '../assets/images/gallery/img2.jpg' + }), + new Image(1, { + img: '../assets/images/gallery/img3.jpg' + }), + new Image(1, { + img: '../assets/images/gallery/img4.jpg' + }) +]; + +const imgToSearchFirst: Image = new Image(0, {img: 'source'}); +const imgToSearchLast: Image = new Image(3, {img: 'source'}); +const imgToSearch: Image = new Image(1, {img: 'source'}); +const imgToSearchHigh: Image = new Image(2000, {img: 'source'}); + +const imgToSearchNegative: Image = new Image(-2, {img: 'source'}); + +const NOT_FOUND = -1; + +describe('image.util', () => { + + describe('#getIndex()', () => { + + it('should find the image obtaining its index', () => { + const firstIndex: number = getIndex(imgToSearchFirst, imagesMock); + const lastIndex: number = getIndex(imgToSearchLast, imagesMock); + const index: number = getIndex(imgToSearch, imagesMock); + expect(firstIndex).toBe(0); + expect(lastIndex).toBe(imagesMock.length - 1); + expect(index).toBe(2); + }); + + it('should find the first image obtaining its index from an array with all the same ids', () => { + const index: number = getIndex(imgToSearch, imagesMockEqualIds); + expect(index).toBe(0); + }); + + it(`shouldn't find the image, so the result index will be -1`, () => { + const indexHigh: number = getIndex(imgToSearchHigh, imagesMock); + expect(indexHigh).toBe(NOT_FOUND); + }); + + it(`should throw an error, because the input image is not valid`, () => { + // @ts-ignore + expect(() => getIndex(null, imagesMock)).toThrowError(`image must be a valid Image object`); + }); + + it(`should throw an error, because the input array of images is not valid`, () => { + // @ts-ignore + expect(() => getIndex(imgToSearch, null)).toThrowError(`arrayOfImages must be a valid Image[]`); + }); + + it(`should throw an error, because the input image hasn't an id`, () => { + expect(() => getIndex({modal: {img: ''}} as Image, imagesMock)).toThrowError(`A numeric Image 'id' is mandatory`); + }); + + it(`should throw an error, because the Image id must be >= 0`, () => { + expect(() => getIndex(imgToSearchNegative, imagesMock)).toThrowError(`Image 'id' must be >= 0`); + }); + + }); +}); diff --git a/projects/ks89/angular-modal-gallery/src/lib/utils/image.util.ts b/projects/ks89/angular-modal-gallery/src/lib/utils/image.util.ts new file mode 100644 index 00000000..a3419fcf --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/utils/image.util.ts @@ -0,0 +1,54 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Image } from '../model/image.class'; + +/** + * Utility function to get the index of the input `image` from `arrayOfImages` + * @param image Image to get the index. The image 'id' must be a number >= 0 + * @param arrayOfImages Image[] to search the image within it + * @returns number the index of the image. -1 if not found. + * @throws an Error if either image or arrayOfImages are not valid, + * or if the input image doesn't contain an 'id', or the 'id' is < 0 + */ +export function getIndex(image: Image, arrayOfImages: Image[]): number { + if (!image) { + throw new Error('image must be a valid Image object'); + } + + if (!arrayOfImages) { + throw new Error('arrayOfImages must be a valid Image[]'); + } + + if (!image.id && image.id !== 0) { + // id = 0 is admitted + throw new Error(`A numeric Image 'id' is mandatory`); + } + + if (image.id < 0) { + throw new Error(`Image 'id' must be >= 0`); + } + + return arrayOfImages.findIndex((val: Image) => val.id === image.id); +} diff --git a/projects/ks89/angular-modal-gallery/src/lib/utils/user-input.util.ts b/projects/ks89/angular-modal-gallery/src/lib/utils/user-input.util.ts new file mode 100644 index 00000000..5950dbdd --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/lib/utils/user-input.util.ts @@ -0,0 +1,109 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +/** + * Key of the keyboard's key `enter` + */ +export const ENTER_KEY: string = 'Enter'; +/** + * Code of the keyboard's key `enter` + */ +export const ENTER_CODE: string = 'Enter'; + +/** + * Key of the keyboard's key `esc` + */ +export const ESC_KEY: string = 'Escape'; +/** + * Code of the keyboard's key `esc` + */ +export const ESC_CODE: string = 'Escape'; +/** + * Key of the keyboard's key 'right arrow' + */ +export const RIGHT_ARROW_KEY: string = 'ArrowRight'; +/** + * Code of the keyboard's key 'right arrow' + */ +export const RIGHT_ARROW_CODE: string = 'ArrowRight'; +/** + * Key of the keyboard's key 'left arrow' + */ +export const LEFT_ARROW_KEY: string = 'ArrowLeft'; +/** + * Code of the keyboard's key 'left arrow' + */ +export const LEFT_ARROW_CODE: string = 'ArrowLeft'; +/** + * Key of the keyboard's key 'left arrow' + */ +export const UP_ARROW_KEY: string = 'ArrowUp'; +/** + * Code of the keyboard's key 'left arrow' + */ +export const UP_ARROW_CODE: string = 'ArrowUp'; +/** + * Key of the keyboard's key 'left arrow' + */ +export const DOWN_ARROW_KEY: string = 'ArrowDown'; +/** + * Code of the keyboard's key 'left arrow' + */ +export const DOWN_ARROW_CODE: string = 'ArrowDown'; +/** + * Key of the keyboard's key `space` + */ +export const SPACE_KEY : string= ''; +/** + * Code of the keyboard's key `space` + */ +export const SPACE_CODE: string = 'Space'; + +/** + * Const to represent the right direction + */ +export const DIRECTION_RIGHT: string = 'right'; +/** + * Const to represent the left direction + */ +export const DIRECTION_LEFT: string = 'left'; + + +/** + * Keycode of the main mouse button + */ +export const MOUSE_MAIN_BUTTON_CLICK = 0; + +/** + * Const NEXT + */ +export const NEXT = 1; +/** + * Const PREV + */ +export const PREV = -1; +/** + * Const NOTHING to represents a situation when it isn't both NEXT and PREV + */ +export const NOTHING = 0; diff --git a/projects/ks89/angular-modal-gallery/src/public-api.ts b/projects/ks89/angular-modal-gallery/src/public-api.ts new file mode 100644 index 00000000..10fef9f1 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/src/public-api.ts @@ -0,0 +1,88 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +/** + * Index file to export all interfaces, enums, classes and so on. + * This file represents the public apis. + */ + +export { GalleryModule } from './lib/modal-gallery.module'; + +export { Action } from './lib/model/action.enum'; +export { Image, ImageEvent, ImageModalEvent } from './lib/model/image.class'; +export type { PlainImage, ModalImage } from './lib/model/image.class'; +export { DescriptionStrategy } from './lib/model/description.interface'; +export type { Description } from './lib/model/description.interface'; +export type { KeyboardConfig } from './lib/model/keyboard-config.interface'; +export type { DotsConfig } from './lib/model/dots-config.interface'; +export type { PreviewConfig } from './lib/model/preview-config.interface'; +export type { AccessibilityConfig } from './lib/model/accessibility.interface'; + +export type { BreakpointsConfig, CarouselPreviewConfig } from './lib/model/carousel-preview-config.interface'; +export type { CarouselConfig } from './lib/model/carousel-config.interface'; +export type { PlayConfig } from './lib/model/play-config.interface'; +export type { CarouselImageConfig } from './lib/model/carousel-image-config.interface'; + +export type { Size } from './lib/model/size.interface'; + +export { ButtonsStrategy, ButtonType } from './lib/model/buttons-config.interface'; +export type { ButtonsConfig, ButtonEvent } from './lib/model/buttons-config.interface'; + +export type { ModalLibConfig, PlainLibConfig, CarouselLibConfig } from './lib/model/lib-config.interface'; + +export type { ModalGalleryConfig } from './lib/model/modal-gallery-config.interface'; + +export type { CurrentImageConfig } from './lib/model/current-image-config.interface'; + +export { LoadingType } from './lib/model/loading-config.interface'; +export type { LoadingConfig } from './lib/model/loading-config.interface'; + +export type { InteractionEvent } from './lib/model/interaction-event.interface'; + +export { KS_DEFAULT_ACCESSIBILITY_CONFIG } from './lib/components/accessibility-default'; +export { + KS_DEFAULT_BTN_FULL_SCREEN, + KS_DEFAULT_BTN_CLOSE, + KS_DEFAULT_BTN_DELETE, + KS_DEFAULT_BTN_DOWNLOAD, + KS_DEFAULT_BTN_EXTURL, + KS_DEFAULT_SIZE +} from './lib/components/upper-buttons/upper-buttons-default'; + +export { + LineLayout, + GridLayout, + PlainGalleryStrategy +} from './lib/model/plain-gallery-config.interface'; +export type { + PlainGalleryConfig, + PlainGalleryLayout, BreakConfig +} from './lib/model/plain-gallery-config.interface'; + +export { ModalGalleryComponent } from './lib/components/modal-gallery/modal-gallery.component'; +export { PlainGalleryComponent } from './lib/components/plain-gallery/plain-gallery.component'; +export { CarouselComponent } from './lib/components/carousel/carousel.component'; + +export { ModalGalleryService } from './lib/components/modal-gallery/modal-gallery.service'; +export { ModalGalleryRef } from './lib/components/modal-gallery/modal-gallery-ref'; diff --git a/projects/ks89/angular-modal-gallery/tsconfig.lib.json b/projects/ks89/angular-modal-gallery/tsconfig.lib.json new file mode 100644 index 00000000..fdcd9fe2 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/tsconfig.lib.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "../../../out-tsc/lib", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "types": [] + }, + "exclude": [ + "**/*.spec.ts" + ] +} diff --git a/projects/ks89/angular-modal-gallery/tsconfig.lib.prod.json b/projects/ks89/angular-modal-gallery/tsconfig.lib.prod.json new file mode 100644 index 00000000..9215caac --- /dev/null +++ b/projects/ks89/angular-modal-gallery/tsconfig.lib.prod.json @@ -0,0 +1,11 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.lib.json", + "compilerOptions": { + "declarationMap": false + }, + "angularCompilerOptions": { + "compilationMode": "partial" + } +} diff --git a/projects/ks89/angular-modal-gallery/tsconfig.spec.json b/projects/ks89/angular-modal-gallery/tsconfig.spec.json new file mode 100644 index 00000000..69ea5088 --- /dev/null +++ b/projects/ks89/angular-modal-gallery/tsconfig.spec.json @@ -0,0 +1,16 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "../../../out-tsc/spec", + "types": [ + "jasmine", + "node" + ] + }, + "include": [ + "**/*.spec.ts", + "**/*.d.ts" + ] +} diff --git a/readme-images/amg-old.png b/readme-images/amg-old.png new file mode 100644 index 00000000..11635c97 Binary files /dev/null and b/readme-images/amg-old.png differ diff --git a/readme-images/amg-svgomg-min.svg b/readme-images/amg-svgomg-min.svg new file mode 100644 index 00000000..15f14cae --- /dev/null +++ b/readme-images/amg-svgomg-min.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/readme-images/amg.png b/readme-images/amg.png new file mode 100644 index 00000000..35e60fae Binary files /dev/null and b/readme-images/amg.png differ diff --git a/readme-images/amg.svg b/readme-images/amg.svg new file mode 100644 index 00000000..f6f42c31 --- /dev/null +++ b/readme-images/amg.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/readme-images/carousel-fix.png b/readme-images/carousel-fix.png new file mode 100644 index 00000000..0ceb3958 Binary files /dev/null and b/readme-images/carousel-fix.png differ diff --git a/readme-images/carousel-full.png b/readme-images/carousel-full.png new file mode 100644 index 00000000..2baf25fb Binary files /dev/null and b/readme-images/carousel-full.png differ diff --git a/readme-images/favicon-128x128.png b/readme-images/favicon-128x128.png new file mode 100644 index 00000000..36405395 Binary files /dev/null and b/readme-images/favicon-128x128.png differ diff --git a/readme-images/favicon-144x144.png b/readme-images/favicon-144x144.png new file mode 100644 index 00000000..ff416433 Binary files /dev/null and b/readme-images/favicon-144x144.png differ diff --git a/readme-images/favicon-152x152.png b/readme-images/favicon-152x152.png new file mode 100644 index 00000000..639f854d Binary files /dev/null and b/readme-images/favicon-152x152.png differ diff --git a/readme-images/favicon-192x192.png b/readme-images/favicon-192x192.png new file mode 100644 index 00000000..4e279875 Binary files /dev/null and b/readme-images/favicon-192x192.png differ diff --git a/readme-images/favicon-32x32.png b/readme-images/favicon-32x32.png new file mode 100644 index 00000000..1b2d0ead Binary files /dev/null and b/readme-images/favicon-32x32.png differ diff --git a/readme-images/favicon-384x384.png b/readme-images/favicon-384x384.png new file mode 100644 index 00000000..a2ca07fa Binary files /dev/null and b/readme-images/favicon-384x384.png differ diff --git a/readme-images/favicon-512x512.png b/readme-images/favicon-512x512.png new file mode 100644 index 00000000..a759eb9a Binary files /dev/null and b/readme-images/favicon-512x512.png differ diff --git a/readme-images/favicon-72x72.png b/readme-images/favicon-72x72.png new file mode 100644 index 00000000..e4a2ad31 Binary files /dev/null and b/readme-images/favicon-72x72.png differ diff --git a/readme-images/favicon-96x96.png b/readme-images/favicon-96x96.png new file mode 100644 index 00000000..f3f24e25 Binary files /dev/null and b/readme-images/favicon-96x96.png differ diff --git a/readme-images/modal1.png b/readme-images/modal1.png new file mode 100644 index 00000000..2f14e1c4 Binary files /dev/null and b/readme-images/modal1.png differ diff --git a/readme-images/modal2.png b/readme-images/modal2.png new file mode 100644 index 00000000..78255a4c Binary files /dev/null and b/readme-images/modal2.png differ diff --git a/readme-images/plain-col.png b/readme-images/plain-col.png new file mode 100644 index 00000000..f9eb12d8 Binary files /dev/null and b/readme-images/plain-col.png differ diff --git a/readme-images/plain-grid.png b/readme-images/plain-grid.png new file mode 100644 index 00000000..a2cb3416 Binary files /dev/null and b/readme-images/plain-grid.png differ diff --git a/readme-images/plain-row.png b/readme-images/plain-row.png new file mode 100644 index 00000000..645d0ab0 Binary files /dev/null and b/readme-images/plain-row.png differ diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts new file mode 100644 index 00000000..20be26e4 --- /dev/null +++ b/src/app/app-routing.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { ModalGalleryExampleComponent } from './modal-gallery/modal-gallery.component'; +import { PlainGalleryExampleComponent } from './plain-gallery/plain-gallery.component'; +import { CarouselExampleComponent } from './carousel/carousel.component'; +import { HomeComponent } from './home/home.component'; + +const routes: Routes = [ + { path: '', component: HomeComponent }, + { path: 'carousel', component: CarouselExampleComponent }, + { path: 'modal', component: ModalGalleryExampleComponent }, + { path: 'plain', component: PlainGalleryExampleComponent } +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes)], + exports: [RouterModule] +}) +export class AppRoutingModule {} diff --git a/src/app/app.component.html b/src/app/app.component.html new file mode 100644 index 00000000..27bca28a --- /dev/null +++ b/src/app/app.component.html @@ -0,0 +1,59 @@ + + +

+ + + +

+
+
+ +
+

A special thank to all authors of icons used in this library:

+
+
+ +
+

A special thanks to all authors of spinners used in this library:

+ +
diff --git a/src/app/app.component.scss b/src/app/app.component.scss new file mode 100644 index 00000000..e06277ac --- /dev/null +++ b/src/app/app.component.scss @@ -0,0 +1,47 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + + +#main-title { + text-align: center; + width: 100%; +} + +#menu { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + + > .menu-item { + margin-left: 10px; + } +} + +.copyright { + text-align: center; +} + +.margin { + margin-left: 15px; + margin-right: 15px; +} diff --git a/src/app/app.component.ts b/src/app/app.component.ts new file mode 100644 index 00000000..17a818a5 --- /dev/null +++ b/src/app/app.component.ts @@ -0,0 +1,33 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component } from '@angular/core'; + +@Component({ + selector: 'ks-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'], + standalone: false +}) +export class AppComponent {} diff --git a/src/app/app.module.ts b/src/app/app.module.ts new file mode 100644 index 00000000..5f336573 --- /dev/null +++ b/src/app/app.module.ts @@ -0,0 +1,71 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; + +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; +import { CarouselExampleComponent } from './carousel/carousel.component'; +import { PlainGalleryExampleComponent } from './plain-gallery/plain-gallery.component'; +import { ModalGalleryExampleComponent } from './modal-gallery/modal-gallery.component'; +import { NavbarComponent } from './navbar/navbar.component'; +import { HomeComponent } from './home/home.component'; +import { IntroHeaderComponent } from './intro-header/intro-header.component'; + +// ********************** angular-modal-gallery ***************************** +import { GalleryModule } from '@ks89/angular-modal-gallery'; // <----------------- angular-modal-gallery library import +// ************************************************************************** + +// ************************ optional font-awesome 5 ************************ +// to install use both `npm i --save @fortawesome/fontawesome-svg-core` and `npm i --save @fortawesome/free-solid-svg-icons` +import { library, dom } from '@fortawesome/fontawesome-svg-core'; +import { faExternalLinkAlt, faPlus, faTimes, faDownload } from '@fortawesome/free-solid-svg-icons'; +library.add(faExternalLinkAlt, faPlus, faTimes, faDownload); +dom.watch(); // Kicks off the process of finding tags and replacing with +// ************************************************************************* + +@NgModule({ + declarations: [ + AppComponent, + CarouselExampleComponent, + PlainGalleryExampleComponent, + ModalGalleryExampleComponent, + NavbarComponent, + HomeComponent, + IntroHeaderComponent + ], + imports: [ + BrowserModule, + FormsModule, + + AppRoutingModule, + + GalleryModule // <-------------------------------------------- @ks89/angular-modal-gallery module import + ], + providers: [], + bootstrap: [AppComponent] +}) +export class AppModule {} diff --git a/src/app/carousel/carousel.component.ts b/src/app/carousel/carousel.component.ts new file mode 100644 index 00000000..a7114bd8 --- /dev/null +++ b/src/app/carousel/carousel.component.ts @@ -0,0 +1,576 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component } from '@angular/core'; + +import { + AccessibilityConfig, + CarouselLibConfig, + Image, + ImageEvent, + ModalGalleryConfig, + ModalGalleryRef, + ModalGalleryService, + ModalLibConfig +} from '@ks89/angular-modal-gallery'; + +@Component({ + selector: 'ks-carousel-page', + templateUrl: './carousel.html', + styleUrls: ['./carousel.scss'], + standalone: false +}) +export class CarouselExampleComponent { + imageIndex = 1; + galleryId = 1; + autoPlay = true; + showArrows = true; + showDots = true; + + LIBCONFIG102: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: false + } + }; + LIBCONFIG103: CarouselLibConfig = { + carouselSlideInfinite: false + }; + LIBCONFIG104: CarouselLibConfig = { + carouselDotsConfig: { + visible: false + } + }; + LIBCONFIG105: CarouselLibConfig = { + carouselPlayConfig: { + autoPlay: false, + interval: 5000, + pauseOnHover: true + } + }; + LIBCONFIG106: CarouselLibConfig = { + carouselPlayConfig: { + autoPlay: true, + interval: 10000, + pauseOnHover: false + } + }; + LIBCONFIG107: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 7, + width: 'auto', + maxHeight: '100px' + } + }; + LIBCONFIG113: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 5 + }, + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + } + }; + LIBCONFIG114: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 5, + width: 'auto', + maxHeight: '100px' + }, + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: true + } + }; + LIBCONFIG115: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 5, + width: 'auto', + maxHeight: '100px' + }, + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: false, + modalGalleryEnable: false + } + }; + LIBCONFIG116: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + number: 7, + clickable: false + } + }; + LIBCONFIG117: CarouselLibConfig = { + carouselImageConfig: { + invertSwipe: true + } + }; + LIBCONFIG118: CarouselLibConfig = { + carouselImageConfig: { + description: { + strategy: 2 + } + } + }; + LIBCONFIG119: CarouselLibConfig = { + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + }, + carouselPreviewsConfig: { + visible: true, + number: 5, + width: 'auto', + maxHeight: '200px' + } + }; + LIBCONFIG120: CarouselLibConfig = { + carouselConfig: { + maxWidth: '766px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + }, + carouselPreviewsConfig: { + visible: true, + number: 5, + width: 'auto', + maxHeight: '150px' + } + }; + LIBCONFIG121: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + breakpoints: { + xSmall: 50, + small: 60, + medium: 80, + large: 150, + xLarge: 180 + } + } + }; + LIBCONFIG122: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + breakpoints: { + xSmall: 50, + small: 60, + medium: 70, + large: 80, + xLarge: 100 + } + }, + carouselConfig: { + maxWidth: '500px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + } + }; + LIBCONFIG124: CarouselLibConfig = { + carouselPreviewsConfig: { + visible: true, + breakpoints: { + xSmall: 50, + small: 60, + medium: 70, + large: 80, + xLarge: 100 + } + }, + carouselConfig: { + maxWidth: '500px', + maxHeight: '400px', + showArrows: true, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + }, + carouselPlayConfig: { + autoPlay: false, + interval: 1, + pauseOnHover: true + } + }; + + imagesRect: Image[] = [ + new Image( + 0, + { + img: '/assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1' + }, + { + img: '/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', + title: 'First image title', + alt: 'First image alt', + ariaLabel: 'First image aria-label' + } + ), + new Image(1, { img: '/assets/images/gallery/pexels-photo-47223.jpeg' }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg' }), + new Image( + 2, + { + img: '/assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3', + title: 'Third image title', + alt: 'Third image alt', + ariaLabel: 'Third image aria-label' + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '/assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4', + title: 'Fourth image title (modal obj)', + alt: 'Fourth image alt (modal obj)', + ariaLabel: 'Fourth image aria-label (modal obj)' + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', + title: 'Fourth image title (plain obj)', + alt: 'Fourth image alt (plain obj)', + ariaLabel: 'Fourth image aria-label (plain obj)' + } + ), + new Image(4, { img: '/assets/images/gallery/pexels-photo-93750.jpeg' }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg' }), + new Image( + 5, + { + img: '/assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6' + }, + { img: '/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg' } + ), + new Image(6, { img: '/assets/images/gallery/pexels-photo-96947.jpeg' }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg' }) + ]; + + imagesRectWithSources: Image[] = [ + new Image( + 0, + { + img: '/assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/milan-pegasus-gallery-statue-480w.jpg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/milan-pegasus-gallery-statue-768w.jpg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/milan-pegasus-gallery-statue-1024w.jpg' } + ] + }, + { + img: '/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', + title: 'First image title', + alt: 'First image alt', + ariaLabel: 'First image aria-label' + } + ), + new Image(1, { img: '/assets/images/gallery/pexels-photo-47223.jpeg', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-47223-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-47223-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-47223-1024w.jpeg' } + ] }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg' }), + new Image( + 2, + { + img: '/assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3', + title: 'Third image title', + alt: 'Third image alt', + ariaLabel: 'Third image aria-label', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-52062-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-52062-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-52062-1024w.jpeg' } + ] + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '/assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4', + title: 'Fourth image title (modal obj)', + alt: 'Fourth image alt (modal obj)', + ariaLabel: 'Fourth image aria-label (modal obj)', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-66943-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-66943-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-66943-1024w.jpeg' } + ] + }, + { + img: '/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', + title: 'Fourth image title (plain obj)', + alt: 'Fourth image alt (plain obj)', + ariaLabel: 'Fourth image aria-label (plain obj)' + } + ), + new Image(4, { img: '/assets/images/gallery/pexels-photo-93750.jpeg', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-93750-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-93750-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-93750-1024w.jpeg' } + ] }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg' }), + new Image( + 5, + { + img: '/assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-94420-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-94420-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-94420-1024w.jpeg' } + ] + }, + { img: '/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg' } + ), + new Image(6, { img: '/assets/images/gallery/pexels-photo-96947.jpeg', + sources: [ + { media: '(max-width: 480px)', srcset: '/assets/images/gallery/pexels-photo-96947-480w.jpeg' }, + { media: '(max-width: 768px)', srcset: '/assets/images/gallery/pexels-photo-96947-768w.jpeg' }, + { media: '(max-width: 1024px)', srcset: '/assets/images/gallery/pexels-photo-96947-1024w.jpeg' } + ] }, { img: '/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg' }) + ]; + + emptyImagesArray: Image[] = []; + + imagesRectNoTitles: Image[] = [ + new Image( + 0, + { img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', title: '' } + ), + new Image( + 1, + { img: '../assets/images/gallery/pexels-photo-47223.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg', title: '' } + ), + new Image( + 2, + { img: '../assets/images/gallery/pexels-photo-52062.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', title: '' } + ), + new Image( + 3, + { img: '../assets/images/gallery/pexels-photo-66943.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', title: '' } + ), + new Image( + 4, + { img: '../assets/images/gallery/pexels-photo-93750.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg', title: '' } + ), + new Image( + 5, + { img: '../assets/images/gallery/pexels-photo-94420.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg', title: '' } + ), + new Image( + 6, + { img: '../assets/images/gallery/pexels-photo-96947.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg', title: '' } + ) + ]; + + fallbackRectImages: Image[] = [ + new Image(0, { + // this file is not available so the browser returns an error + img: '../assets/images/gallery/UNEXISTING_IMG1.jpg', + // because the img above doesn't exists, the library will use this file + fallbackImg: '../assets/images/gallery/fallback-carousel1.jpg' + }), + new Image(1, { + img: '../assets/images/gallery/UNEXISTING_IMG2.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel2.jpg' + }), + new Image( + 2, + { + img: '../assets/images/gallery/UNEXISTING_IMG3.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel3.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG3.png', + fallbackImg: '../assets/images/gallery/fallback-carousel3.jpg' + } + ), + new Image(3, { + img: '../assets/images/gallery/UNEXISTING_IMG4.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel4.jpg' + }), + new Image( + 4, + { + img: '../assets/images/gallery/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel5.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback-carousel5.jpg' + } + ) + ]; + + accessibilityConfig: AccessibilityConfig = { + backgroundAriaLabel: 'CUSTOM Modal gallery full screen background', + backgroundTitle: 'CUSTOM background title', + + plainGalleryContentAriaLabel: 'CUSTOM Plain gallery content', + plainGalleryContentTitle: 'CUSTOM plain gallery content title', + + modalGalleryContentAriaLabel: 'CUSTOM Modal gallery content', + modalGalleryContentTitle: 'CUSTOM modal gallery content title', + + loadingSpinnerAriaLabel: 'CUSTOM The current image is loading. Please be patient.', + loadingSpinnerTitle: 'CUSTOM The current image is loading. Please be patient.', + + mainContainerAriaLabel: 'CUSTOM Current image and navigation', + mainContainerTitle: 'CUSTOM main container title', + mainPrevImageAriaLabel: 'CUSTOM Previous image', + mainPrevImageTitle: 'CUSTOM Previous image', + mainNextImageAriaLabel: 'CUSTOM Next image', + mainNextImageTitle: 'CUSTOM Next image', + + dotsContainerAriaLabel: 'CUSTOM Image navigation dots', + dotsContainerTitle: 'CUSTOM dots container title', + dotAriaLabel: 'CUSTOM Navigate to image number', + + previewsContainerAriaLabel: 'CUSTOM Image previews', + previewsContainerTitle: 'CUSTOM previews title', + previewScrollPrevAriaLabel: 'CUSTOM Scroll previous previews', + previewScrollPrevTitle: 'CUSTOM Scroll previous previews', + previewScrollNextAriaLabel: 'CUSTOM Scroll next previews', + previewScrollNextTitle: 'CUSTOM Scroll next previews', + + carouselContainerAriaLabel: 'Current image and navigation', + carouselContainerTitle: '', + carouselPrevImageAriaLabel: 'Previous image', + carouselPrevImageTitle: 'Previous image', + carouselNextImageAriaLabel: 'Next image', + carouselNextImageTitle: 'Next image', + carouselPreviewsContainerAriaLabel: 'Image previews', + carouselPreviewsContainerTitle: '', + carouselPreviewScrollPrevAriaLabel: 'Scroll previous previews', + carouselPreviewScrollPrevTitle: 'Scroll previous previews', + carouselPreviewScrollNextAriaLabel: 'Scroll next previews', + carouselPreviewScrollNextTitle: 'Scroll next previews' + }; + + constructor(private modalGalleryService: ModalGalleryService) {} + + addRandomImage(): void { + const imageToCopy: Image = this.imagesRect[Math.floor(Math.random() * this.imagesRect.length)]; + const newImage: Image = new Image(this.imagesRect.length - 1 + 1, imageToCopy.modal, imageToCopy.plain); + this.imagesRect = [...this.imagesRect, newImage]; + } + + onChangeAutoPlay(): void { + this.autoPlay = !this.autoPlay; + } + + onChangeShowArrows(): void { + this.showArrows = !this.showArrows; + } + + onChangeShowDots(): void { + this.showDots = !this.showDots; + } + + // output evets + onShow(event: ImageEvent): void { + console.log('show', event); + } + + onFirstImage(event: ImageEvent): void { + console.log('firstImage', event); + } + + onLastImage(event: ImageEvent): void { + console.log('lastImage', event); + } + + getLibConfig108(autoPlay: boolean, showArrows: boolean, showDots: boolean): CarouselLibConfig { + return { + carouselDotsConfig: { + visible: showDots + }, + carouselPlayConfig: { + autoPlay: autoPlay, + interval: 3000, + pauseOnHover: true + }, + carouselConfig: { + maxWidth: '100%', + maxHeight: '400px', + showArrows: showArrows, + objectFit: 'cover', + keyboardEnable: true, + modalGalleryEnable: false + } + } as CarouselLibConfig; + } + + openModal(imageIndex: number, id: number): void { + const imageToShow: Image = this.imagesRect[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: this.imagesRect, + currentImage: imageToShow + } as ModalGalleryConfig) as ModalGalleryRef; + } +} diff --git a/src/app/carousel/carousel.html b/src/app/carousel/carousel.html new file mode 100644 index 00000000..ee04ac8c --- /dev/null +++ b/src/app/carousel/carousel.html @@ -0,0 +1,215 @@ +

Carousel

+
+ +

Basic examples

+
+
+

A1 - (id=100) - carousel example (minimal with all defaults) without content projection

+
+ +
+
+
+

A2 - (id=101) - carousel example (minimal with all defaults)

+
+ +
This is my projected content!
+
+
+
+
+

A3 - (id=102) - carousel example without previews

+
+ +
This is my projected content!
+
+
+
+
+

A4 - (id=103) - carousel example without infinite sliding

+
+ +
This is my projected content!
+
+
+
+
+

A5 - (id=104) - carousel example without dots

+
+ +
This is my projected content!
+
+
+
+
+

A6 - (id=105) - carousel example without auto-play (but all other playConfig properties have default values)

+
+ +
This is my projected content!
+
+
+
+
+

A7 - (id=106) - carousel example with a custom playConfig (10s of interval and pauseOnHover disabled)

+
+ +
This is my projected content!
+
+
+
+
+

A8 - (id=107) - carousel example with a custom previewConfig (7 previews with 'auto' width and 100px of height)

+
+ +
This is my projected content!
+
+
+
+
+

A9 - (id=108) - carousel example with buttons to enable/disable autoplay, arrows and other properties

+

Autoplay:

+

Show Arrows:

+

Show Dots:

+
+ +
This is my projected content!
+
+
+
+
+

A10 - (id=109) - carousel example (minimal with all defaults) with outputs

+
+ +
+
+
+

A11 - (id=110) - carousel example with fallback images when it's not possible to load normal images (to fix issue #194)

+
+ +
+
+
+

A12 - (id=111) - carousel example without title attribute on images

+
+ +
+
+
+

A13 - (id=112) - carousel example with an empty images array.

+

Carousel component doesn't support empty images arrays! To prevent runtime errors, you should use an *ngIf to remove the carousel when there are no images.

+
+ +
+
+
+ +

Examples with custom style

+
+

B1 - (id=113) - carousel example with fixed maxWidth (766px) and custom previews

+

By default, on bigger screen, previews will have height = 200px. If you want you can customize it or also change all breakpoint widths.

+
+ +
This is my projected content!
+
+
+
+
+

B2 - (id=114) - carousel example with fixed maxWidth (766px), custom previews and open modal on click

+
+ +
This is my projected content!
+
+
+
+
+

B3 - (id=115) - carousel example with fixed maxWidth (766px), custom previews and keyboard navigation disabled (for example left/right arrows)

+
+ +
This is my projected content!
+
+
+
+
+

B4 - (id=116) - carousel example with 7 images and unclickable previews

+
+ +
This is my projected content!
+
+
+
+
+ +

Examples with custom current image

+
+

C1 - (id=117) - carousel example with invert swipe on touchscreen devices

+
+ +
This is my projected content!
+
+
+
+
+

C2 - (id=118) - carousel example with description

+
+ +
This is my projected content!
+
+
+
+ + +

Examples with custom previews height

+

I know that these examples look bad, but the purpose is to show only how the library handles heights. + In both examples I didn't set breakpoints, so it will be used default values, but with the maxHeight specified

+

If F1, the maxHeight is 200px, but also the default breakpoints has 200px as maximum size, so the result will be very bad on bigger screen. + In F2, I'm using a smaller maxHeight, so previews won't be taller than 150px, despite the default breakpoints on bigger screens (200px).

+
+

F1 - (id=119) - carousel example with fixed maxWidth (766px) and custom previews (maxHeight 200px)

+
+ +
This is my projected content!
+
+
+
+
+

F2 - (id=120) - carousel example with fixed maxWidth (766px) and custom previews (maxHeight 150px)

+
+ +
This is my projected content!
+
+
+
+ + +

Examples with custom heights for previews (to try responsiveness)

+
+
+

G1 - (id=121) - carousel example (previews with different heights based on the window's width: xSmall: 50, small: 60, medium: 80, large: 150, xLarge: 180)

+
+ +
+
+
+

G2 - (id=122) - carousel example with fixed maxWidth (500px) (previews with different heights based on the window's width: xSmall: 50, small: 60, medium: 70, large: 80, xLarge: 100)

+
+ +
+
+

Examples using sources (to improve LCP)

+
+
+

H1 - (id=123) - carousel example (minimal with all defaults) without content projection - using sources

+
+ +
+
+

H2 - (id=124) - carousel example with fixed maxWidth (500px) (previews with different heights based on the window's width: xSmall: 50, small: 60, medium: 70, large: 80, xLarge: 100) - using sources

+
+ +
+
+
diff --git a/src/app/carousel/carousel.scss b/src/app/carousel/carousel.scss new file mode 100644 index 00000000..547c14f9 --- /dev/null +++ b/src/app/carousel/carousel.scss @@ -0,0 +1,157 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +:host { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; +} + +section { + width: 100%; +} + +h2, h3, p { + margin-left: 20px; +} + +$text-color: #fff; +$background: rgba(0, 0, 0, .7); + +.my-app-custom-plain-container-row { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + .my-app-custom-image-row { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-column { + align-items: center; + display: flex; + flex-direction: column; + justify-content: flex-start; + + .my-app-custom-image-column { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-with-desc { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + figure { + margin: 0; + position: relative; + + img { + max-width: 100%; + height: auto; + cursor: pointer; + } + + figcaption { + background: rgba(0, 0, 0, .5); + color: #fff; + font-size: 85%; + padding: 5px; + position: absolute; + bottom: 3px; + left: 0; + right: 0; + } + } + + .description { + font-weight: bold; + text-align: center; + } + + .my-app-custom-image-with-desc { + height: auto; + margin-right: 2px; + width: 200px; + align-self: start; + } +} + +.more { + background: $background; + cursor: pointer; + color: $text-color; + padding-top: 4px; + height: 46px; + position: absolute; + text-align: center; + width: 50px; +} + + +.projected { + color: white; + font-weight: 600; + font-size: 24px; + text-align: center; + position: absolute; + top: 50%; + width: 100%; + pointer-events: none; +} + +.title { + margin-top: 40px; +} diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts new file mode 100644 index 00000000..82d07f20 --- /dev/null +++ b/src/app/home/home.component.ts @@ -0,0 +1,33 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component } from '@angular/core'; + +@Component({ + selector: 'ks-home-page', + templateUrl: './home.html', + styleUrls: ['./home.scss'], + standalone: false +}) +export class HomeComponent {} diff --git a/src/app/home/home.html b/src/app/home/home.html new file mode 100644 index 00000000..f5ec1261 --- /dev/null +++ b/src/app/home/home.html @@ -0,0 +1,12 @@ + +
+ +
+

Welcome

+

This is the official live example of @ks89/angular-modal-gallery. + To get started quickly you can try and check the sourcecode of this example.

+

If you need the full documentation with all apis, this is the official documentation website.

+ +

The official documentation is available at ks89.github.io/angular-modal-gallery-2024-v13.github.io

+
+ diff --git a/src/app/home/home.scss b/src/app/home/home.scss new file mode 100644 index 00000000..8c5e86a7 --- /dev/null +++ b/src/app/home/home.scss @@ -0,0 +1,26 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +.container { + margin-left: 15px; + margin-right: 15px; +} diff --git a/src/app/intro-header/intro-header.component.ts b/src/app/intro-header/intro-header.component.ts new file mode 100644 index 00000000..b6c7ba73 --- /dev/null +++ b/src/app/intro-header/intro-header.component.ts @@ -0,0 +1,33 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa (Ks89) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { Component } from '@angular/core'; + +@Component({ + selector: 'ks-intro-header', + templateUrl: 'intro-header.html', + styleUrls: ['intro-header.scss'], + standalone: false +}) +export class IntroHeaderComponent {} diff --git a/src/app/intro-header/intro-header.html b/src/app/intro-header/intro-header.html new file mode 100644 index 00000000..94cdd372 --- /dev/null +++ b/src/app/intro-header/intro-header.html @@ -0,0 +1,8 @@ +
+ @ks89/angular-modal-gallery icon +

@ks89/angular-modal-gallery

+

Image gallery for Angular >=19

+

Currently v13

+
+
diff --git a/src/app/intro-header/intro-header.scss b/src/app/intro-header/intro-header.scss new file mode 100644 index 00000000..d0f1cbc3 --- /dev/null +++ b/src/app/intro-header/intro-header.scss @@ -0,0 +1,73 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa (Ks89) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// search all occurrences in all code, also html, because it's everywhere +$color-primary: #101010; +$color-secondary: #9e9e9e; +$color-white: #FFF; +$color-black: #000; +$color-light-black: #343A40; +$color-code: #c100e0; +$color-url: #0060b7; +$color-warning: #880012; + +//$font-huge: 24px; +$font-big: 18px; +$font-middle: 14px; +$font-small: 12px; +$font-very-small: 10px; + +.intro-header { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + background-color: $color-primary; + background: linear-gradient(135deg, $color-primary, $color-secondary); + margin-top: 10px; + padding-bottom: 1px; + color: $color-white; + + h1 { + color: $color-white; + font-size: 3rem; + } +} + +.project-title { + margin-top: 20px; + font-size: 2.8rem; + text-align: center; +} + +img { + margin-top: 25px; + border-radius: 10px +} + +.lead { + font-size: 1rem; + text-align: center; + color: #d4d4d4; +} diff --git a/src/app/modal-gallery/libconfigs.ts b/src/app/modal-gallery/libconfigs.ts new file mode 100644 index 00000000..fdf8c729 --- /dev/null +++ b/src/app/modal-gallery/libconfigs.ts @@ -0,0 +1,583 @@ +import { + ButtonsStrategy, + ButtonType, + Description, + DescriptionStrategy, + KS_DEFAULT_BTN_CLOSE, + KS_DEFAULT_BTN_DELETE, + KS_DEFAULT_BTN_DOWNLOAD, + KS_DEFAULT_BTN_EXTURL, + KS_DEFAULT_BTN_FULL_SCREEN, + LoadingConfig, + LoadingType, + ModalLibConfig, + Size +} from '@ks89/angular-modal-gallery'; + +const DEFAULT_SIZE_PREVIEWS: Size = { + width: '100px', + height: 'auto' +}; + +// Examples A +export const LIBCONFIG_406: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: true, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +export const LIBCONFIG_407: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: false, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +export const LIBCONFIG_408: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: false, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +// Examples B +export const LIBCONFIG_500: ModalLibConfig = { + previewConfig: { + visible: false + }, + dotsConfig: { + visible: false + } +}; + +export const LIBCONFIG_501: ModalLibConfig = { + buttonsConfig: { + visible: false, + strategy: ButtonsStrategy.DEFAULT + }, + previewConfig: { + visible: false + }, + dotsConfig: { + visible: false + } +}; + +export const LIBCONFIG_502: ModalLibConfig = { + buttonsConfig: { + visible: false, + strategy: ButtonsStrategy.DEFAULT + }, + slideConfig: { + infinite: false, + sidePreviews: { + show: false, + size: DEFAULT_SIZE_PREVIEWS + } + }, + previewConfig: { + visible: false + }, + dotsConfig: { + visible: false + } +}; + +export const LIBCONFIG_503: ModalLibConfig = { + previewConfig: { + visible: true, + size: { + width: '90px', + height: 'auto' + } + } +}; + +export const LIBCONFIG_504: ModalLibConfig = { + enableCloseOutside: false +}; + +export const LIBCONFIG_505: ModalLibConfig = { + currentImageConfig: { downloadable: false }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.DEFAULT + } +}; + +export const LIBCONFIG_506: ModalLibConfig = { + currentImageConfig: { downloadable: true }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.DEFAULT + } +}; + +export const LIBCONFIG_507: ModalLibConfig = { + currentImageConfig: { downloadable: true }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.SIMPLE + } +}; + +export const LIBCONFIG_508: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: false, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +export const LIBCONFIG_509: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: true, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +export const LIBCONFIG_510: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: false, + type: LoadingType.STANDARD + } + } +}; +export const LIBCONFIG_511: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.STANDARD + } + } +}; +export const LIBCONFIG_512: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.CIRCULAR + } + } +}; +export const LIBCONFIG_513: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.BARS + } + } +}; +export const LIBCONFIG_514: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.DOTS + } + } +}; +export const LIBCONFIG_515: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.CUBE_FLIPPING + } + } +}; +export const LIBCONFIG_516: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.CIRCLES + } + } +}; +export const LIBCONFIG_517: ModalLibConfig = { + currentImageConfig: { + loadingConfig: { + enable: true, + type: LoadingType.EXPLOSING_SQUARES + } + } +}; + +export const LIBCONFIG_518: ModalLibConfig = { + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.DEFAULT + } +}; +export const LIBCONFIG_519: ModalLibConfig = { + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.SIMPLE + } +}; +export const LIBCONFIG_520: ModalLibConfig = { + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.ADVANCED + } +}; +export const LIBCONFIG_521: ModalLibConfig = { + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.FULL + } +}; + +// default buttons but extUrl will open the link in a new tab instead of the current one +// this requires to specify all buttons manually (also if they are not really custom) +export const LIBCONFIG_522: ModalLibConfig = { + currentImageConfig: { downloadable: true }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.CUSTOM, + buttons: [ + { + className: 'ext-url-image', + type: ButtonType.EXTURL, + extUrlInNewTab: true // <--- this is the important thing to understand this example + }, + { + className: 'download-image', + type: ButtonType.DOWNLOAD + }, + { + className: 'close-image', + type: ButtonType.CLOSE + } + ] + } +}; + +export const LIBCONFIG_523: ModalLibConfig = { + currentImageConfig: { + downloadable: true + }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.CUSTOM, + buttons: [ + // KS_DEFAULT_BTN_ROTATE, + KS_DEFAULT_BTN_FULL_SCREEN, + KS_DEFAULT_BTN_DELETE, + KS_DEFAULT_BTN_EXTURL, + KS_DEFAULT_BTN_DOWNLOAD, + KS_DEFAULT_BTN_CLOSE + ] + } +}; + +export const LIBCONFIG_524: ModalLibConfig = { + currentImageConfig: { + downloadable: true + }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.CUSTOM, + buttons: [ + { + className: 'fas fa-plus white', + type: ButtonType.CUSTOM, + ariaLabel: 'custom plus aria label', + title: 'custom plus title', + fontSize: '20px' + }, + { + className: 'fas fa-times white', + type: ButtonType.CLOSE, + ariaLabel: 'custom close aria label', + title: 'custom close title', + fontSize: '20px' + }, + { + className: 'fas fa-download white', + type: ButtonType.DOWNLOAD, + ariaLabel: 'custom download aria label', + title: 'custom download title', + fontSize: '20px' + }, + { + className: 'fas fa-external-link-alt white', + type: ButtonType.EXTURL, + ariaLabel: 'custom exturl aria label', + title: 'custom exturl title', + fontSize: '20px' + } + ] + } +}; + +export const LIBCONFIG_525: ModalLibConfig = { + previewConfig: { + visible: true, + mobileVisible: true + } +}; + +// Examples C +export const LIBCONFIG_600: ModalLibConfig = { + keyboardConfig: { + esc: 'KeyQ', + left: 'ArrowDown', + right: 'ArrowUp' + } +}; + +export const LIBCONFIG_601: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + imageText: 'Look this image ', + numberSeparator: ' of ', + beforeTextDescription: ' => ' + } + } +}; + +export const LIBCONFIG_602: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.HIDE_IF_EMPTY, + imageText: 'Look this image ', + numberSeparator: ' of ', + beforeTextDescription: ' => ' + } + } +}; + +export const LIBCONFIG_603: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_HIDDEN, + // you should build this value programmatically with the result of (show)="..()" event + customFullDescription: 'Custom description of the current visible image' + // if customFullDescription !== undefined, all other fields will be ignored + // imageText: '', + // numberSeparator: '', + // beforeTextDescription: '', + } + } +}; + +export const LIBCONFIG_604: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + // you should build this value programmatically with the result of (show)="..()" event + customFullDescription: 'Custom description of the current visible image' + // if customFullDescription !== undefined, all other fields will be ignored + // imageText: '', + // numberSeparator: '', + // beforeTextDescription: '', + } + } +}; + +export const LIBCONFIG_605: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + imageText: 'Look this image ', + numberSeparator: ' of ', + beforeTextDescription: ' => ' + } + } +}; + +export const LIBCONFIG_606: ModalLibConfig = { + currentImageConfig: { + description: { + strategy: DescriptionStrategy.ALWAYS_VISIBLE, + imageText: 'Look this image ', + numberSeparator: ' of ', + beforeTextDescription: ' => ', + style: { + bgColor: 'rgba(255,0,0,.5)', + textColor: 'blue', + marginTop: '3px', + marginBottom: '0px', + marginLeft: '5px', + marginRight: '5px', + position: 'absolute', + top: '0px', + height: '25px' + // be careful to use width, in particular with % values + } + } + } +}; + +export const LIBCONFIG_607: ModalLibConfig = { + previewConfig: { + visible: true, + number: 1 + } +}; + +export const LIBCONFIG_608: ModalLibConfig = { + previewConfig: { + visible: true, + number: 5 + } +}; + +export const LIBCONFIG_609: ModalLibConfig = { + previewConfig: { + visible: true, + arrows: false + } +}; + +export const LIBCONFIG_610: ModalLibConfig = { + previewConfig: { + visible: true, + clickable: false + } +}; + +export const LIBCONFIG_611: ModalLibConfig = { + previewConfig: { + visible: true, + size: { width: '30px', height: '30px' } + } +}; + +export const LIBCONFIG_612: ModalLibConfig = { + accessibilityConfig: { + backgroundAriaLabel: 'CUSTOM Modal gallery full screen background', + backgroundTitle: 'CUSTOM background title', + + plainGalleryContentAriaLabel: 'CUSTOM Plain gallery content', + plainGalleryContentTitle: 'CUSTOM plain gallery content title', + + modalGalleryContentAriaLabel: 'CUSTOM Modal gallery content', + modalGalleryContentTitle: 'CUSTOM modal gallery content title', + + loadingSpinnerAriaLabel: 'CUSTOM The current image is loading. Please be patient.', + loadingSpinnerTitle: 'CUSTOM The current image is loading. Please be patient.', + + mainContainerAriaLabel: 'CUSTOM Current image and navigation', + mainContainerTitle: 'CUSTOM main container title', + mainPrevImageAriaLabel: 'CUSTOM Previous image', + mainPrevImageTitle: 'CUSTOM Previous image', + mainNextImageAriaLabel: 'CUSTOM Next image', + mainNextImageTitle: 'CUSTOM Next image', + + dotsContainerAriaLabel: 'CUSTOM Image navigation dots', + dotsContainerTitle: 'CUSTOM dots container title', + dotAriaLabel: 'CUSTOM Navigate to image number', + + previewsContainerAriaLabel: 'CUSTOM Image previews', + previewsContainerTitle: 'CUSTOM previews title', + previewScrollPrevAriaLabel: 'CUSTOM Scroll previous previews', + previewScrollPrevTitle: 'CUSTOM Scroll previous previews', + previewScrollNextAriaLabel: 'CUSTOM Scroll next previews', + previewScrollNextTitle: 'CUSTOM Scroll next previews', + + carouselContainerAriaLabel: 'Current image and navigation', + carouselContainerTitle: '', + carouselPrevImageAriaLabel: 'Previous image', + carouselPrevImageTitle: 'Previous image', + carouselNextImageAriaLabel: 'Next image', + carouselNextImageTitle: 'Next image', + carouselPreviewsContainerAriaLabel: 'Image previews', + carouselPreviewsContainerTitle: '', + carouselPreviewScrollPrevAriaLabel: 'Scroll previous previews', + carouselPreviewScrollPrevTitle: 'Scroll previous previews', + carouselPreviewScrollNextAriaLabel: 'Scroll next previews', + carouselPreviewScrollNextTitle: 'Scroll next previews' + } +}; + +export const LIBCONFIG_613: ModalLibConfig = { + currentImageConfig: { + navigateOnClick: false + } +}; + +// Examples D +export const LIBCONFIG_701: ModalLibConfig = { + currentImageConfig: { + downloadable: true + }, + buttonsConfig: { + visible: true, + strategy: ButtonsStrategy.SIMPLE + } +}; + +export const LIBCONFIG_702: ModalLibConfig = { + currentImageConfig: { + invertSwipe: true + } +}; + +export const LIBCONFIG_703: ModalLibConfig = { + slideConfig: { + infinite: true, + sidePreviews: { + show: true, + size: DEFAULT_SIZE_PREVIEWS + } + } +}; + +// Examples E +export const LIBCONFIG_800: ModalLibConfig = { + slideConfig: { + playConfig: { + autoPlay: true, + interval: 5000, + pauseOnHover: true + } + } +}; + +export const LIBCONFIG_801: ModalLibConfig = { + slideConfig: { + infinite: true, + playConfig: { + autoPlay: true, + interval: 5000, + pauseOnHover: false + } + } +}; + +export const LIBCONFIG_802: ModalLibConfig = { + slideConfig: { + playConfig: { + autoPlay: true, + interval: 1000, + pauseOnHover: false + } + } +}; + +// Examples F +export const LIBCONFIG_900: ModalLibConfig = { + slideConfig: { + infinite: false + }, + currentImageConfig: { + loadingConfig: { enable: true, type: LoadingType.STANDARD } as LoadingConfig, + description: { strategy: DescriptionStrategy.ALWAYS_VISIBLE } as Description + } +}; diff --git a/src/app/modal-gallery/modal-gallery.component.ts b/src/app/modal-gallery/modal-gallery.component.ts new file mode 100644 index 00000000..1672e87b --- /dev/null +++ b/src/app/modal-gallery/modal-gallery.component.ts @@ -0,0 +1,763 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { TemplateRef } from '@angular/core'; +import { ViewChild } from '@angular/core'; +import { Component, OnDestroy } from '@angular/core'; +import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; + +import { + Action, + ButtonEvent, + ButtonType, + Image, + ImageModalEvent, + ModalGalleryService, + ModalGalleryRef, + ModalGalleryConfig, + ModalLibConfig +} from '@ks89/angular-modal-gallery'; +import { Subscription } from 'rxjs'; + +import * as libConfigs from './libconfigs'; + +@Component({ + selector: 'ks-modal-gallery-page', + templateUrl: './modal-gallery.html', + styleUrls: ['./modal-gallery.scss'], + standalone: false +}) +export class ModalGalleryExampleComponent implements OnDestroy { + /** + * A custom template to illustrate the customization of previews rendering. + */ + @ViewChild('previewsTemplate') + previewsTemplate?: TemplateRef; + + imageIndex = 0; + galleryId = 1; + isPlaying = true; + // Examples A + CONFIG406: ModalLibConfig = libConfigs.LIBCONFIG_406; + CONFIG407: ModalLibConfig = libConfigs.LIBCONFIG_407; + CONFIG408: ModalLibConfig = libConfigs.LIBCONFIG_408; + // Examples B + CONFIG500: ModalLibConfig = libConfigs.LIBCONFIG_500; + CONFIG501: ModalLibConfig = libConfigs.LIBCONFIG_501; + CONFIG502: ModalLibConfig = libConfigs.LIBCONFIG_502; + CONFIG503: ModalLibConfig = libConfigs.LIBCONFIG_503; + CONFIG504: ModalLibConfig = libConfigs.LIBCONFIG_504; + CONFIG505: ModalLibConfig = libConfigs.LIBCONFIG_505; + CONFIG506: ModalLibConfig = libConfigs.LIBCONFIG_506; + CONFIG507: ModalLibConfig = libConfigs.LIBCONFIG_507; + CONFIG508: ModalLibConfig = libConfigs.LIBCONFIG_508; + CONFIG509: ModalLibConfig = libConfigs.LIBCONFIG_509; + CONFIG510: ModalLibConfig = libConfigs.LIBCONFIG_510; + CONFIG511: ModalLibConfig = libConfigs.LIBCONFIG_511; + CONFIG512: ModalLibConfig = libConfigs.LIBCONFIG_512; + CONFIG513: ModalLibConfig = libConfigs.LIBCONFIG_513; + CONFIG514: ModalLibConfig = libConfigs.LIBCONFIG_514; + CONFIG515: ModalLibConfig = libConfigs.LIBCONFIG_515; + CONFIG516: ModalLibConfig = libConfigs.LIBCONFIG_516; + CONFIG517: ModalLibConfig = libConfigs.LIBCONFIG_517; + CONFIG518: ModalLibConfig = libConfigs.LIBCONFIG_518; + CONFIG519: ModalLibConfig = libConfigs.LIBCONFIG_519; + CONFIG520: ModalLibConfig = libConfigs.LIBCONFIG_520; + CONFIG521: ModalLibConfig = libConfigs.LIBCONFIG_521; + CONFIG522: ModalLibConfig = libConfigs.LIBCONFIG_522; + CONFIG523: ModalLibConfig = libConfigs.LIBCONFIG_523; + CONFIG524: ModalLibConfig = libConfigs.LIBCONFIG_524; + CONFIG525: ModalLibConfig = libConfigs.LIBCONFIG_525; + // Examples C + CONFIG600: ModalLibConfig = libConfigs.LIBCONFIG_600; + CONFIG601: ModalLibConfig = libConfigs.LIBCONFIG_601; + CONFIG602: ModalLibConfig = libConfigs.LIBCONFIG_602; + CONFIG603: ModalLibConfig = libConfigs.LIBCONFIG_603; + CONFIG604: ModalLibConfig = libConfigs.LIBCONFIG_604; + CONFIG605: ModalLibConfig = libConfigs.LIBCONFIG_605; + CONFIG606: ModalLibConfig = libConfigs.LIBCONFIG_606; + CONFIG607: ModalLibConfig = libConfigs.LIBCONFIG_607; + CONFIG608: ModalLibConfig = libConfigs.LIBCONFIG_608; + CONFIG609: ModalLibConfig = libConfigs.LIBCONFIG_609; + CONFIG610: ModalLibConfig = libConfigs.LIBCONFIG_610; + CONFIG611: ModalLibConfig = libConfigs.LIBCONFIG_611; + CONFIG612: ModalLibConfig = libConfigs.LIBCONFIG_612; + CONFIG613: ModalLibConfig = libConfigs.LIBCONFIG_613; + // Examples D + CONFIG701: ModalLibConfig = libConfigs.LIBCONFIG_701; + CONFIG702: ModalLibConfig = libConfigs.LIBCONFIG_702; + CONFIG703: ModalLibConfig = libConfigs.LIBCONFIG_703; + // Examples E + CONFIG800: ModalLibConfig = libConfigs.LIBCONFIG_800; + CONFIG801: ModalLibConfig = libConfigs.LIBCONFIG_801; + CONFIG802: ModalLibConfig = libConfigs.LIBCONFIG_802; + // Example F + CONFIG900: ModalLibConfig = libConfigs.LIBCONFIG_900; + + images: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: '../assets/images/gallery/img2.jpg', + description: 'Description 2' + }), + new Image( + 2, + { + img: '../assets/images/gallery/img3.jpg', + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new Image(3, { + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new Image(4, { img: '../assets/images/gallery/img5.jpg' }, { img: '../assets/images/gallery/thumbs/img5.jpg' }) + ]; + + emptyImagesArray: Image[] = []; + + imagesRectNoTitles: Image[] = [ + new Image( + 0, + { img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', title: '' } + ), + new Image( + 1, + { img: '../assets/images/gallery/pexels-photo-47223.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg', title: '' } + ), + new Image( + 2, + { img: '../assets/images/gallery/pexels-photo-52062.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', title: '' } + ), + new Image( + 3, + { img: '../assets/images/gallery/pexels-photo-66943.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', title: '' } + ), + new Image( + 4, + { img: '../assets/images/gallery/pexels-photo-93750.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg', title: '' } + ), + new Image( + 5, + { img: '../assets/images/gallery/pexels-photo-94420.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg', title: '' } + ), + new Image( + 6, + { img: '../assets/images/gallery/pexels-photo-96947.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg', title: '' } + ) + ]; + + fallbackImages: Image[] = [ + new Image(0, { + // this file is not available so the browser returns an error + img: '../assets/images/gallery/UNEXISTING_IMG1.jpg', + // because the img above doesn't exists, the library will use this file + fallbackImg: '../assets/images/gallery/fallback1.jpg' + }), + new Image(1, { + img: '../assets/images/gallery/UNEXISTING_IMG2.jpg', + fallbackImg: '../assets/images/gallery/fallback2.jpg' + }), + new Image( + 2, + { + img: '../assets/images/gallery/UNEXISTING_IMG3.jpg', + fallbackImg: '../assets/images/gallery/fallback3.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG3.png', + fallbackImg: '../assets/images/gallery/fallback3.jpg' + } + ), + new Image(3, { + img: '../assets/images/gallery/UNEXISTING_IMG4.jpg', + fallbackImg: '../assets/images/gallery/fallback4.jpg' + }), + new Image( + 4, + { + img: '../assets/images/gallery/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback5.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback5.jpg' + } + ) + ]; + + // array of images (obviously with different id) where paths are the same. + // to prevent caching issues I have to append '?index'. + sameImages: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg?1', + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: '../assets/images/gallery/img1.jpg?2', + extUrl: 'http://www.google.com' + }), + new Image(2, { + img: '../assets/images/gallery/img1.jpg?3', + extUrl: 'http://www.google.com' + }) + ]; + + // example of a png converted into base64 using https://www.base64-image.de/ or other similar websites + base64String = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABN0lEQV' + + 'R4nO3SQQ2AQBDAwAVlaMEhCkAV' + + 'b2RcQmcU9NEZAAAAAOD/tvN675k5VoewxLOvLmAtA8QZIM4AcQaIM0CcAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4gwQZ4A4A8QZIM4AcQaIM0C' + + 'cAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4gwQZ4A4A8QZIM4AcQaIM0CcAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4g' + + 'wQZ4A4A8QZIM4AcQaIM0CcAeIMEGeAOAPEGSDOAHEGiDNAnAHiDBBngDgDxBkgzgBxBogzQJwB4gwQZ4A4A8QZIM4AcQaIM0CcAeIMEGeAOAPEGQAAAAAA4Pc+8asEoPPGq' + + 'xUAAAAASUVORK5CYII'; + + base64RedString = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAY1BMVEX/AAD/////WVn/+vr/qan/Nzf/ERH/2tr/s7P/KSn/' + + '7+//vr7/0ND/W1v/6+v/m5v/4+P/U1P/HR3/o6P/rq7/g4P/k5P/t7f/dXX/SEj/zMz/ZWX/h4f/bm7/amr/np7/yMhDG/2oAAAC8ElEQVR4nO3dC3KqQBCF4WkHERHFRyKIL/' + + 'a/ymDuVYMMFipTbbfnW8H5S4lQVGUMaWe4B3iHQvlQKB8K5UOhfCiUD4XyoVA+FJ7Myijd5dvBO9nmuzQqZ68X2mI9NO9suC7s84VxNuAO6GSQxU8VJvuQe3pn4T55uLDYcK9+' + + '0KZ4qDB574vPbej+HF2Fcc499km563p0FAbcQ18QdCi0B+6VLzk0fjtuC0dj7o0vGo/uF064B/agvFcYca/rRdReeOTe1pNjW6HkP6J1gbtQwzV4NnEVJtyrepU0C2M599ldhH' + + 'GjcMq9qWfT28KUe1Hv0nrhnHuPB/Na4YJ7jgeLv4UZ9xovsmuhXXKP8WJpL4Ur7i2erC6Fun4Kr8Jz4Rf3Em++/hdKf+htN/5XqOuGtC75LfzmnuHR96nQ6v2SVl9TWxVq/pKevq' + + 'aG1twjvFpXhTLeLz1rQMZyb/DMmhH3BM9GRudjxVVmtN51n62M1DdpXeVG2rveR22MxLe9jxgazfdsJ2Oj9en3THsfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + + 'AAAAAAAAAAAAAAgHba/+98+AFnI+g/30L/GSX6z5nRf1aQ/vOe9J/Zpf/cNf1n533A+Yf6z7DUfw6p/rNkVX9Nkw850/kDzuXWf7Y6ab37Xl0K7ZJ7ixdLeykknQ8YGV0LacG9xo' + + 'MF/S2cc8/xYF4rpJR7T+9SqhfSlHtRz6Z0Wxjr+lEM40ahstvThJqFNOFe1aMJuQop4N7Vm4DchXTkXtaTI7UVUsS9rRcRtRequBZLuldII+mPw+MR3S8ke+De+JKDvQ1qFMr+kx' + + 'o0cxyFFEt945bHjhpXYXV/I/HN8DBxtrgLiQpp74Y3RUtJW2H1Oe7l3IuHe/fnd7+wuh4zGe+lBpnr+utSWLHF+r0vyeG6aPw+PFT4a1ZG6S7fDt7JNt+lUTnrsL5LoWwolA+F8q' + + 'FQPhTKh0L5UCgfCuVDoXw/lnQz7dm7GjoAAAAASUVORK5CYII='; + base64GreenString = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAgMAAADQNkYNAAAADFBMVEUAAAAy/ysy/ysy/ysyTcibAAAAA3RSTlMA2r/af0d' + + 'WAAAAQUlEQVRo3u3YMREAMAzEsJAMyZJsMXy3XORdBFySJK3qxFXH1Y1DEARBEARBEARBEARBEARBkNmk436mvSRJ0o4eOKL2P81eyn8AAAAASUVORK5CYII='; + + base64Image: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.base64String); + base64RedImage: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.base64RedString); + base64GreenImage: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.base64GreenString); + + imagesBase64: Image[] = [ + new Image(0, { + img: this.base64Image, + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: this.base64GreenImage, + description: 'Description 2' + }), + new Image( + 2, + { + img: this.base64RedImage, + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + img: this.base64RedImage, + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ) + ]; + + imagesCustomDownloadFileName: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg', + downloadFileName: 'first-img.jpg' + }), + new Image(1, { + img: this.base64Image, + downloadFileName: 'second-img-base64.jpg' + }) + ]; + + imagesHtmlDescriptions: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: '../assets/images/gallery/img2.jpg', + description: '
  1. This is
  2. the description
  3. number
  4. 2
' + }), + new Image( + 2, + { + img: '../assets/images/gallery/img3.jpg', + description: '
  • Description
  • 3
', + extUrl: 'http://www.google.com' + }, + { + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new Image(3, { + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new Image(4, { img: '../assets/images/gallery/img5.jpg' }, { img: '../assets/images/gallery/thumbs/img5.jpg' }) + ]; + + imagesRect: Image[] = [ + new Image( + 0, + { + img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1' + }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg' } + ), + new Image(1, { img: '../assets/images/gallery/pexels-photo-47223.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg' }), + new Image( + 2, + { + img: '../assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3' + }, + { + img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '../assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4' + }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg' } + ), + new Image(4, { img: '../assets/images/gallery/pexels-photo-93750.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg' }), + new Image( + 5, + { + img: '../assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6' + }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg' } + ), + new Image(6, { img: '../assets/images/gallery/pexels-photo-96947.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg' }) + ]; + + imagesMixedSizes: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/pexels-photo-135230.png', + description: 'Description 1' + }), + new Image(1, { + img: '../assets/images/gallery/pexels-photo-547115.jpeg' + }), + new Image(2, { + img: '../assets/images/gallery/pexels-photo-556664.jpeg', + description: 'Description 3' + }), + new Image(3, { + img: '../assets/images/gallery/pexels-photo-787594.jpeg', + description: 'Description 4' + }), + new Image(4, { + img: '../assets/images/gallery/pexels-photo-803105.jpeg' + }) + ]; + + // example of images with small previews (they are different files) to show + // loading spinners + imagesForLoadingSpinner: Image[] = [ + new Image( + 0, + { + img: '../assets/images/loading-spinner-samples/pexels-photo-74506.jpg' + }, + { img: '../assets/images/loading-spinner-samples/pexels-photo-74506-thumb.jpg' } + ), + new Image( + 1, + { + img: '../assets/images/loading-spinner-samples/pexels-photo-106006.jpg' + }, + { img: '../assets/images/loading-spinner-samples/pexels-photo-106006-thumb.jpg' } + ), + new Image( + 2, + { + img: '../assets/images/loading-spinner-samples/pexels-photo-464336.jpg' + }, + { img: '../assets/images/loading-spinner-samples/pexels-photo-464336-thumb.jpg' } + ), + new Image( + 3, + { + img: '../assets/images/loading-spinner-samples/pexels-photo.jpg' + }, + { img: '../assets/images/loading-spinner-samples/pexels-photo-thumb.jpg' } + ), + new Image( + 4, + { + img: '../assets/images/loading-spinner-samples/traffic-highway-lights-night-56891.jpg' + }, + { img: '../assets/images/loading-spinner-samples/traffic-highway-lights-night-56891-thumb.jpg' } + ) + ]; + + // array with a single image inside (the first one) + singleImage: Image[] = [this.images[0]]; + + imagesInfiniteAutoAdd: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg?1', + extUrl: 'http://www.google.com' + }) + ]; + + private count = 0; + + // subscriptions to receive events from the gallery + // REMEMBER TO call unsubscribe(); in ngOnDestroy (see below) + private closeSubscription: Subscription | undefined; + private showSubscription: Subscription | undefined; + private firstImageSubscription: Subscription | undefined; + private lastImageSubscription: Subscription | undefined; + private hasDataSubscription: Subscription | undefined; + private buttonBeforeHookSubscription: Subscription | undefined; + private buttonAfterHookSubscription: Subscription | undefined; + + // this variable is used only for example of auto navigation + // tslint:disable-next-line:no-any + private timeout: any; + + constructor(private modalGalleryService: ModalGalleryService, private sanitizer: DomSanitizer) {} + + openModalWithAutoClose(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + + this.showSubscription = dialogRef.show$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - show$: ', event); + const galleryId: number = event.galleryId; + console.log(`onShowAutoCloseExample with id=${galleryId} action: ` + Action[event.action]); + console.log('onShowAutoCloseExample result:' + event.result); + console.log('Starting timeout of 3 seconds to close modal gallery automatically'); + // clear previous timeout + clearTimeout(this.timeout); + this.timeout = setTimeout(() => { + console.log('setTimeout end - closing gallery with id=' + galleryId); + this.modalGalleryService.close(galleryId, false); + }, 3000); + }); + } + + addRandomImage(): void { + // add to images array + const imageToCopy: Image = this.images[Math.floor(Math.random() * this.images.length)]; + const newImage: Image = new Image(this.images.length - 1 + 1, imageToCopy.modal, imageToCopy.plain); + this.images = [...this.images, newImage]; + // add also to imagesRect + const imageRectToCopy: Image = this.imagesRect[Math.floor(Math.random() * this.imagesRect.length)]; + const newImageRect: Image = new Image(this.imagesRect.length - 1 + 1, imageRectToCopy.modal, imageRectToCopy.plain); + this.imagesRect = [...this.imagesRect, newImageRect]; + // add also to imagesMixedSizes + const imageMixToCopy: Image = this.imagesMixedSizes[Math.floor(Math.random() * this.imagesMixedSizes.length)]; + const newImageMix: Image = new Image(this.imagesMixedSizes.length - 1 + 1, imageMixToCopy.modal, imageMixToCopy.plain); + this.imagesMixedSizes = [...this.imagesMixedSizes, newImageMix]; + } + + openModal(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + if(imagesArrayToUse.length === 0) { + console.error('Cannot open modal-gallery because images array cannot be empty'); + return; + } + if(imageIndex > imagesArrayToUse.length - 1) { + console.error('Cannot open modal-gallery because imageIndex must be valid'); + return; + } + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig, + } as ModalGalleryConfig) as ModalGalleryRef; + } + + openModalWithOutputs(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.closeSubscription = dialogRef.close$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - close$: ', event); + }); + this.showSubscription = dialogRef.show$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - show$: ', event); + }); + this.firstImageSubscription = dialogRef.firstImage$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - firstImage$: ', event); + }); + this.lastImageSubscription = dialogRef.lastImage$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - lastImage$: ', event); + }); + this.hasDataSubscription = dialogRef.hasData$.subscribe((event: ImageModalEvent) => { + // angular-modal-gallery will emit this event if it will load successfully input images + console.log('OUTPUT - hasData$: ', event); + }); + this.buttonBeforeHookSubscription = dialogRef.buttonBeforeHook$.subscribe((event: ButtonEvent) => { + console.log('OUTPUT - buttonBeforeHook$: ', event); + if (!event || !event.button) { + return; + } + // Invoked after a click on a button, but before that the related + // action is applied. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + if (event.button.type === ButtonType.DELETE) { + // remove the current image and reassign all other to the array of images + console.log('delete in app with images count ' + this.images.length); + this.images = this.images.filter((val: Image) => event.image && val.id !== event.image.id); + } + }); + this.buttonAfterHookSubscription = dialogRef.buttonAfterHook$.subscribe((event: ButtonEvent) => { + if (!event || !event.button) { + return; + } + // Invoked after both a click on a button and its related action. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + }); + } + + openModalWithDeleteButton(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: [...imagesArrayToUse], + currentImage: Object.assign({}, imageToShow), + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.buttonBeforeHookSubscription = dialogRef.buttonBeforeHook$.subscribe((event: ButtonEvent) => { + console.log('OUTPUT - buttonBeforeHook$:', event); + if (!event || !event.button) { + return; + } + // Invoked after a click on a button, but before that the related + // action is applied. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + }); + this.buttonAfterHookSubscription = dialogRef.buttonAfterHook$.subscribe((event: ButtonEvent) => { + console.log('OUTPUT - buttonAfterHook$:', event); + if (!event || !event.button) { + return; + } + if (event.button.type === ButtonType.DELETE) { + // remove the current image and reassign all other to the array of images + this.images = this.images.filter((val: Image) => event.image && val.id !== event.image.id); + this.modalGalleryService.updateModalImages(this.images); + } + // Invoked after both a click on a button and its related action. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + }); + } + + openModalWithAddButton(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.buttonBeforeHookSubscription = dialogRef.buttonBeforeHook$.subscribe((event: ButtonEvent) => { + if (!event || !event.button) { + return; + } + // Invoked after a click on a button, but before that the related + // action is applied. + + if (event.button.type === ButtonType.CUSTOM) { + console.log('adding a new random image at the end'); + this.addRandomImage(); + setTimeout(() => { + this.modalGalleryService.updateModalImages(this.images); + }, 0); + } + }); + this.buttonAfterHookSubscription = dialogRef.buttonAfterHook$.subscribe((event: ButtonEvent) => { + console.log('OUTPUT - buttonAfterHook$:', event); + if (!event || !event.button) { + return; + } + // Invoked after both a click on a button and its related action. + // For instance: this method will be invoked after a click + // of 'close' button, but before that the modal gallery + // will be really closed. + }); + } + + openModalWithAutoAdd(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.showSubscription = dialogRef.show$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - show$: ', event); + if (this.count !== 0) { + return; + } + const interval = setInterval(() => { + const imageToCopy: Image = this.images[Math.floor(Math.random() * this.images.length)]; + const newImage: Image = new Image(this.imagesInfiniteAutoAdd.length - 1 + 1, imageToCopy.modal, imageToCopy.plain); + newImage.modal.img += `?${this.imagesInfiniteAutoAdd.length + 1}`; + this.imagesInfiniteAutoAdd = [...this.imagesInfiniteAutoAdd, newImage]; + this.modalGalleryService.updateModalImages(this.imagesInfiniteAutoAdd); + this.count++; + if (this.count === 4) { + clearInterval(interval); + } + }, 2000); + }); + } + + openModalWithAutoUpdate(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig + } as ModalGalleryConfig) as ModalGalleryRef; + this.showSubscription = dialogRef.show$.subscribe((event: ImageModalEvent) => { + console.log('OUTPUT - show$: ', event); + if (this.count !== 0) { + return; + } + const indexToRefresh = 1; + const image: Image = new Image(1, { + img: '../assets/images/gallery/img5.jpg', + description: 'Description 2 updated with imag5.jpg' + }); + + console.log('updating image at index ' + indexToRefresh + ', after 4 seconds'); + + // create the new array of images with the updated image inside + const newImages: Image[] = [...this.images]; + newImages[indexToRefresh] = image; + + setTimeout(() => { + this.modalGalleryService.updateModalImages(newImages); + console.log('image updated successfully!'); + }, 4000); + }); + } + + autoPlayButton(config: ModalLibConfig): boolean { + this.isPlaying = !this.isPlaying; + if (config && config.slideConfig && config.slideConfig.playConfig) { + config.slideConfig.playConfig.autoPlay = this.isPlaying; + } + return this.isPlaying; + } + + trackById(index: number, item: Image): number { + return item.id; + } + + openModalWithPreviewsTemplate(id: number, imagesArrayToUse: Image[], imageIndex: number, libConfig?: ModalLibConfig): void { + if(imagesArrayToUse.length === 0) { + console.error('Cannot open modal-gallery because images array cannot be empty'); + return; + } + if(imageIndex > imagesArrayToUse.length - 1) { + console.error('Cannot open modal-gallery because imageIndex must be valid'); + return; + } + const imageToShow: Image = imagesArrayToUse[imageIndex]; + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: imagesArrayToUse, + currentImage: imageToShow, + libConfig, + previewsTemplate: this.previewsTemplate, + } as ModalGalleryConfig) as ModalGalleryRef; + } + + ngOnDestroy(): void { + // release resources to prevent memory leaks and unexpected behaviours + if (this.closeSubscription) { + this.closeSubscription.unsubscribe(); + } + if (this.showSubscription) { + this.showSubscription.unsubscribe(); + } + if (this.firstImageSubscription) { + this.firstImageSubscription.unsubscribe(); + } + if (this.lastImageSubscription) { + this.lastImageSubscription.unsubscribe(); + } + if (this.hasDataSubscription) { + this.hasDataSubscription.unsubscribe(); + } + if (this.buttonBeforeHookSubscription) { + this.buttonBeforeHookSubscription.unsubscribe(); + } + if (this.buttonAfterHookSubscription) { + this.buttonAfterHookSubscription.unsubscribe(); + } + } +} diff --git a/src/app/modal-gallery/modal-gallery.html b/src/app/modal-gallery/modal-gallery.html new file mode 100644 index 00000000..2a264c8b --- /dev/null +++ b/src/app/modal-gallery/modal-gallery.html @@ -0,0 +1,325 @@ +

Modal Gallery

+
+ +

If you want, you can add a random image to every example + +

+
+

Index to open:   

+
+
+

WARNING: remember to use always different ids across your application!!!

+
+
+
+

Minimal examples

+
+

A1 - (id=400) - Minimal demo - all defaults (images array)

+ +
+
+

A1bis - (id=401) - Minimal demo - all defaults with rect images (imagesRect array)

+ +
+
+

A1tris - (id=402) - Minimal demo - all defaults with images of different sizes (imagesMixedSizes array)

+ +
+
+

A2 - (id=403) - Minimal demo - listen for events

+

I added 'openModalWithOutputs()' public method to listen for events

+ +
+
+

A3 - (id=405) - Minimal demo - single image (singleImage array)

+ +
+
+

A4 - (id=406) - Minimal demo - single image with infinite sliding enabled (to fix issue #156)

+ +
+
+

A5 - (id=407) - Minimal demo - two images with infinite sliding enabled (to fix issue #156)

+ +
+
+

A6 - (id=408) - Minimal demo - three image with infinite sliding enabled (to fix issue #156)

+ +
+
+

A7 - (id=409) - Minimal demo - use fallback images when it's not possible to load normal images (to fix issue #194)

+ +
+
+
+
+

Simple examples

+
+

B1 - (id=500) - Simple demo - only current image and buttons (previews and dots are hidden)

+ +
+
+

B2 - (id=501) - Simple demo - only current image (buttons, previews and dots are hidden)

+ +
+
+

B3 - (id=502) - Simple demo - only current image (side previews, buttons, previews and dots are hidden)

+ +
+
+

B3bis - (id=503) - Simple demo - custom preview size

+ +
+
+

B4 - (id=504) - Simple demo - disable closeOutside

+ +
+
+

B5 - (id=505) - Simple demo - no downloadable at all

+ +
+
+

B6 - (id=506) - Simple demo - no download button (only with keyboard)

+ +
+
+

B7 - (id=507) - Simple demo - download with both button and keyboard

+ +
+
+

B8 - (id=508) - Simple demo - infinite sliding but NO side previews

+ +
+
+

B9 - (id=509) - Simple demo - infinite sliding and side previews

+ +
+
+

B10 - (id=510) - Simple demo - disable loading spinner

+ +
+
+

B11 - (id=511) - Simple demo - loading spinner of type Standard

+ +
+
+

B12 - (id=512) - Simple demo - loading spinner of type Circular

+ +
+
+

B13 - (id=513) - Simple demo - loading spinner of type Bars

+ +
+
+

B14 - (id=514) - Simple demo - loading spinner of type Dots

+ +
+
+

B15 - (id=515) - Simple demo - loading spinner of type Cube Flipping

+ +
+
+

B16 - (id=516) - Simple demo - loading spinner of type Circles

+ +
+
+

B17 - (id=517) - Simple demo - loading spinner of type Explosing Squares

+ +
+ +
+

B18 - (id=518) - Simple demo - buttons config DEFAULT strategy (only close)

+ +
+
+

B19 - (id=519) - Simple demo - buttons config SIMPLE strategy (close and download)

+ +
+
+

B20 - (id=520) - Simple demo - buttons config ADVANCED strategy (close, download and exturl in the current + tab)

+ +
+
+

B21 - (id=521) - Simple demo - buttons config FULL strategy (all buttons)

+

I added also 'openModalWithDeleteButton()' public method to support delete button

+ +
+
+

B22 - (id=522) - Simple demo - buttons config CUSTOM strategy with exturl in ANOTHER TAB ('_blank')

+ +
+
+

B23 - (id=523) - Simple demo - buttons config CUSTOM but with all default buttons already included in the library

+

I added also 'openModalWithDeleteButton()' public method to support delete button

+ +
+
+

B24 - (id=524) - Simple demo - buttons config CUSTOM strategy with Font Awesome 5

+

I added also 'openModalWithAddButton()' public method to support delete button

+
+ +
+
+

B25 - (id=525) - Previews visible on mobile screen

+

Added PreviewConfig.mobileVisible configuration param

+
+ +
+
+
+
+

Advanced examples

+
+

C1 - (id=600) - Advanced demo - custom keyboard ('up'/'down' arrows and 'q' to close)

+ +
+
+

C2 - (id=601) - Advanced demo - custom description always visible

+ +
+
+

C3 - (id=602) - Advanced demo - custom description hide if empty

+ +
+
+

C4 - (id=603) - Advanced demo - custom description always hidden

+ +
+
+

C5 - (id=604) - Advanced demo - custom FULL description always visible

+ +
+
+

C6 - (id=605) - Advanced demo - custom HTML description always visible

+ +
+
+

C7 - (id=606) - Advanced demo - custom description style (always visible)

+ +
+ +
+

C8 - (id=607) - Advanced demo - preview custom configuration with 1 image (clickable)

+ +
+ +
+

C9 - (id=608) - Advanced demo - preview custom configuration with 5 images (clickable)

+ +
+ +
+

C10 - (id=609) - Advanced demo - preview custom configuration without arrows (clickable)

+ +
+
+

C11 - (id=610) - Advanced demo - preview custom configuration not clickable

+ +
+
+

C12 - (id=611) - Advanced demo - preview custom configuration with custom size

+ +
+ +
+

C13 - (id=612) - Advanced demo - accessibility config

+ +
+ +
+

C14 - (id=613) - Advanced demo - disable clicks on current image in modal-image

+ +
+ +
+

C15 - (id=614) - Advanced demo - after 3 seconds it closes modal gallery automatically with galleryService close method

+

Attention: please check the console to understand what it's happening!

+

Timer will clear and restart every time you show another image!

+ +
+ +
+
+
+

Other examples

+
+

D1 - (id=700) - Other demo - base64 images

+ +
+ +
+

D2 - (id=701) - Other demo - custom file name, used when downloaded

+ +
+ +
+

D3 - (id=702) - Other demo - invert touchscreen swipe direction

+ +
+ +
+

D4 - (id=703) - Other demo - infinite sliding and automatic add of images when the gallery is visible

+ +
+ +
+

D5 - (id=704) - Other demo - automatic update of the second image (index=1) via gallery service (open the second image and wait some seconds to see the result)

+ +
+ +
+

D6 - (id=705) - Other demo - remove title attribute on images

+ +
+ +
+

D7 - (id=706) - Other demo - modal gallery with an empty images array

+ +
+ +
+
+
+

AutoPlay examples

+
+

E1 - (id=800) - AutoPlay demo - with interval=5000 and pauseOnHover enabled

+ +
+
+

E2 - (id=801) - AutoPlay demo - with interval=5000, pauseOnHover disabled and infinite is enabled

+ +
+
+

E3 - (id=802) - AutoPlay demo - with interval=1000 and pauseOnHover disabled

+

+ +
+ + +
+
+
+

Experimental examples*

+

* these will be either improved or removed in next versions

+
+

F1 - (id=900) - Experimental demo - infinite sliding with only one image to see if side arrows are hidden

+ +
+
+

F2 - (id=901) - Experimental demo - an array of Images with the same source file (different classes/ids and paths with appended '?imageIndex' to prevent caching issues)

+ +
+
+

F3 - (id=902) - Experimental demo - 'previews' rendering customization (via Angular templates)

+ +
+
{{preview?.modal?.description ?? ' '}}
+
+ +
+
+
+ +
+ diff --git a/src/app/modal-gallery/modal-gallery.scss b/src/app/modal-gallery/modal-gallery.scss new file mode 100644 index 00000000..994466cd --- /dev/null +++ b/src/app/modal-gallery/modal-gallery.scss @@ -0,0 +1,177 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +:host { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + margin-left: 20px; + margin-right: 20px; +} + +$text-color: #fff; +$background: rgba(0, 0, 0, .7); + +button { + background-color: #0060b7; + color: white; + height: 25px; + width: auto; + border: 0; + border-radius: 5px; + cursor: pointer; + + &:hover { + background-color: #0086ff; + } +} + +.my-app-custom-plain-container-row { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + .my-app-custom-image-row { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-column { + align-items: center; + display: flex; + flex-direction: column; + justify-content: flex-start; + + .my-app-custom-image-column { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-with-desc { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + figure { + margin: 0; + position: relative; + + img { + max-width: 100%; + height: auto; + cursor: pointer; + } + + figcaption { + background: rgba(0, 0, 0, .5); + color: #fff; + font-size: 85%; + padding: 5px; + position: absolute; + bottom: 3px; + left: 0; + right: 0; + } + } + + .description { + font-weight: bold; + text-align: center; + } + + .my-app-custom-image-with-desc { + height: auto; + margin-right: 2px; + width: 200px; + align-self: start; + } +} + +.more { + background: $background; + cursor: pointer; + color: $text-color; + padding-top: 4px; + height: 46px; + position: absolute; + text-align: center; + width: 50px; +} + + +.transcluded { + color: white; + font-weight: 600; + font-size: 24px; + text-align: center; + position: absolute; + top: 50%; + width: 100%; + pointer-events: none; +} + +.title { + margin-top: 40px; +} + +.preview-block { + margin-right: 10px; +} +.preview-description { + color: #fff; + margin-bottom: 3px; +} +.preview-description, +.preview-default { + text-align: center; +} diff --git a/src/app/navbar/navbar.component.ts b/src/app/navbar/navbar.component.ts new file mode 100644 index 00000000..5d9df903 --- /dev/null +++ b/src/app/navbar/navbar.component.ts @@ -0,0 +1,63 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa (Ks89) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { Component } from '@angular/core'; +import { Router } from '@angular/router'; +import { BreakpointObserver } from '@angular/cdk/layout'; + +@Component({ + selector: 'ks-navbar', + templateUrl: 'navbar.html', + styleUrls: ['navbar.scss'], + standalone: false +}) +export class NavbarComponent { + navbarHeight = '56px'; + // path: string = PATH + '/assets/amg.svg'; + + collapsed = false; + + constructor(private router: Router, breakpointObserver: BreakpointObserver) { + breakpointObserver.observe(['(min-width: 990px)']).subscribe(result => { + if (result.matches) { + console.log('min width 990px'); + this.collapsed = false; + } + }); + } + + isNavItemActive(location: string): string { + return this.router.url.includes(location) ? 'active' : ''; + } + + onNavigateTo(path: string): void { + this.collapsed = false; + this.router.navigate([path]); + } + + onToggle(): void { + this.collapsed = !this.collapsed; + this.navbarHeight = this.collapsed ? '56px' : '150px'; + } +} diff --git a/src/app/navbar/navbar.html b/src/app/navbar/navbar.html new file mode 100644 index 00000000..f95de0c4 --- /dev/null +++ b/src/app/navbar/navbar.html @@ -0,0 +1,68 @@ + + + + + diff --git a/src/app/navbar/navbar.scss b/src/app/navbar/navbar.scss new file mode 100644 index 00000000..d7e45bc7 --- /dev/null +++ b/src/app/navbar/navbar.scss @@ -0,0 +1,233 @@ +/* + * MIT License + * + * Copyright (c) 2017-2024 Stefano Cappa (Ks89) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +nav { + padding-top: 8px; + padding-bottom: 8px; + padding-left: 16px; + padding-right: 16px; +} + +ul { + margin-top: 0; + margin-bottom: 0; + padding-left: 0; +} + +nav.nav-expanded { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + background-color: #343A40; + padding-top: 8px; + padding-left: 16px; + padding-bottom: 8px; + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 10; + + > .navbar-hamburger { + display: none; + background-color: #343A40; + border-color: rgba(255, 255, 255, .1); + + @media screen and (max-width: 990px) { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + cursor: pointer; + padding-top: 4px; + padding-bottom: 4px; + padding-left: 12px; + padding-right: 12px; + } + } + + > .navbar-wrapper { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + + @media screen and (max-width: 990px) { + display: none; + } + + > .navbar-brand { + font-size: 16px; + color: #ffffff; + font-weight: 400; + margin-left: 8px; + margin-right: 8px; + cursor: pointer; + + > img { + border-radius: 3px + } + + &:hover { + color: #bdbdbd; + } + } + + > .navbar-nav { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + list-style: none; + + > .nav-item { + cursor: pointer; + color: #e2e2e2; + + > a.nav-link { + color: #b9b9b9; + font-size: 14px; + font-weight: 400; + margin-left: 8px; + margin-right: 8px; + + &:hover { + color: #E2E2E2; + } + } + } + } + } + + > #githubButtons { + margin-right: 30px; + @media only screen and (max-width: 1059px) { + display: none; + } + + > .github-badge { + margin-left: 8px; + } + } +} + + +// cexpanded on mobile devices after pressing the hamburger button +nav.nav-collapsed { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + flex-wrap: wrap; + background-color: #343A40; + padding-top: 8px; + padding-left: 16px; + padding-bottom: 8px; + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 10; + + > .navbar-hamburger { + display: none; + background-color: #343A40; + border-color: rgba(255, 255, 255, .1); + + @media screen and (max-width: 990px) { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + cursor: pointer; + padding-top: 4px; + padding-bottom: 4px; + padding-left: 12px; + padding-right: 12px; + } + } + + > .navbar-wrapper { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + margin-top: 8px; + width: 100%; + + > .navbar-brand { + font-size: 16px; + color: #ffffff; + font-weight: 400; + margin-left: 8px; + margin-right: 8px; + margin-top: 8px; + margin-bottom: 8px; + cursor: pointer; + width: 100%; + + > img { + border-radius: 3px + } + + &:hover { + color: #bdbdbd; + } + } + + > .navbar-nav { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + width: 100%; + list-style: none; + + > .nav-item { + cursor: pointer; + color: #e2e2e2; + width: 100%; + margin-top: 8px; + margin-bottom: 8px; + + > a.nav-link { + color: #b9b9b9; + font-size: 14px; + font-weight: 400; + margin-left: 8px; + margin-right: 8px; + + &:hover { + color: #E2E2E2; + } + } + } + } + } +} + + + diff --git a/src/app/plain-gallery/plain-gallery.component.ts b/src/app/plain-gallery/plain-gallery.component.ts new file mode 100644 index 00000000..bc54d635 --- /dev/null +++ b/src/app/plain-gallery/plain-gallery.component.ts @@ -0,0 +1,296 @@ +/* + The MIT License (MIT) + + Copyright (c) 2017-2024 Stefano Cappa (Ks89) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import { Component } from '@angular/core'; + +import { + GridLayout, + Image, + LineLayout, + PlainGalleryConfig, + PlainGalleryStrategy, + ModalGalleryService, + ModalGalleryRef, + PlainLibConfig +} from '@ks89/angular-modal-gallery'; + +@Component({ + selector: 'ks-plain-gallery-page', + templateUrl: './plain-gallery.html', + styleUrls: ['./plain-gallery.scss'], + standalone: false +}) +export class PlainGalleryExampleComponent { + constructor(private modalGalleryService: ModalGalleryService) {} + + plainGalleryRow: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout({ width: '80px', height: '80px' }, { length: 2, wrap: true }, 'flex-start') + }; + plainGalleryRowSpaceAround: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout({ width: '50px', height: '50px' }, { length: 2, wrap: true }, 'space-around') + }; + plainGalleryRowATags: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.ROW, + layout: new LineLayout({ width: '95px', height: '63px' }, { length: 4, wrap: true }, 'flex-start'), + // when advanced is defined, additionalBackground: '50% 50%/cover' will be used by default. + // I added this here, to be more explicit. + advanced: { aTags: true, additionalBackground: '50% 50%/cover' } + }; + + plainGalleryColumn: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.COLUMN, + layout: new LineLayout({ width: '50px', height: '50px' }, { length: 3, wrap: true }, 'flex-start') + }; + + plainGalleryGrid: PlainGalleryConfig = { + strategy: PlainGalleryStrategy.GRID, + layout: new GridLayout({ width: '80px', height: '80px' }, { length: 3, wrap: true }) + }; + + images: Image[] = [ + new Image(0, { + img: '../assets/images/gallery/img1.jpg', + extUrl: 'http://www.google.com' + }), + new Image(1, { + img: '../assets/images/gallery/img2.jpg', + description: 'Description 2' + }), + new Image( + 2, + { + img: '../assets/images/gallery/img3.jpg', + description: 'Description 3', + extUrl: 'http://www.google.com' + }, + { + img: '../assets/images/gallery/thumbs/img3.png', + title: 'custom title 2', + alt: 'custom alt 2', + ariaLabel: 'arial label 2' + } + ), + new Image(3, { + img: '../assets/images/gallery/img4.jpg', + description: 'Description 4', + extUrl: 'http://www.google.com' + }), + new Image(4, { img: '../assets/images/gallery/img5.jpg' }, { img: '../assets/images/gallery/thumbs/img5.jpg' }) + ]; + + emptyImagesArray: Image[] = []; + + fallbackImages: Image[] = [ + new Image(0, { + // this file is not available so the browser returns an error + img: '../assets/images/gallery/UNEXISTING_IMG1.jpg', + // because the img above doesn't exists, the library will use this file + fallbackImg: '../assets/images/gallery/fallback1.jpg' + }), + new Image(1, { + img: '../assets/images/gallery/UNEXISTING_IMG2.jpg', + fallbackImg: '../assets/images/gallery/fallback2.jpg' + }), + new Image( + 2, + { + img: '../assets/images/gallery/UNEXISTING_IMG3.jpg', + fallbackImg: '../assets/images/gallery/fallback3.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG3.png', + fallbackImg: '../assets/images/gallery/fallback3.jpg' + } + ), + new Image(3, { + img: '../assets/images/gallery/UNEXISTING_IMG4.jpg', + fallbackImg: '../assets/images/gallery/fallback4.jpg' + }), + new Image( + 4, + { + img: '../assets/images/gallery/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback5.jpg' + }, + { + img: '../assets/images/gallery/thumbs/UNEXISTING_IMG5.jpg', + fallbackImg: '../assets/images/gallery/fallback5.jpg' + } + ) + ]; + + imagesRect: Image[] = [ + new Image( + 0, + { + img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', + description: 'Description 1' + }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg' } + ), + new Image(1, { img: '../assets/images/gallery/pexels-photo-47223.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg' }), + new Image( + 2, + { + img: '../assets/images/gallery/pexels-photo-52062.jpeg', + description: 'Description 3' + }, + { + img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', + description: 'Description 3' + } + ), + new Image( + 3, + { + img: '../assets/images/gallery/pexels-photo-66943.jpeg', + description: 'Description 4' + }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg' } + ), + new Image(4, { img: '../assets/images/gallery/pexels-photo-93750.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg' }), + new Image( + 5, + { + img: '../assets/images/gallery/pexels-photo-94420.jpeg', + description: 'Description 6' + }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg' } + ), + new Image(6, { img: '../assets/images/gallery/pexels-photo-96947.jpeg' }, { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg' }) + ]; + + imagesRectNoTitles: Image[] = [ + new Image( + 0, + { img: '../assets/images/gallery/milan-pegasus-gallery-statue.jpg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg', title: '' } + ), + new Image( + 1, + { img: '../assets/images/gallery/pexels-photo-47223.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-47223.jpg', title: '' } + ), + new Image( + 2, + { img: '../assets/images/gallery/pexels-photo-52062.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-52062.jpg', title: '' } + ), + new Image( + 3, + { img: '../assets/images/gallery/pexels-photo-66943.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-66943.jpg', title: '' } + ), + new Image( + 4, + { img: '../assets/images/gallery/pexels-photo-93750.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-93750.jpg', title: '' } + ), + new Image( + 5, + { img: '../assets/images/gallery/pexels-photo-94420.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-94420.jpg', title: '' } + ), + new Image( + 6, + { img: '../assets/images/gallery/pexels-photo-96947.jpeg', title: '' }, + { img: '../assets/images/gallery/thumbs/t-pexels-photo-96947.jpg', title: '' } + ) + ]; + + libConfigPlainGalleryRow: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryRow + }; + libConfigPlainGalleryRowSpaceAround: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryRowSpaceAround + }; + libConfigPlainGalleryRowATags: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryRowATags + }; + libConfigPlainGalleryColumn: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryColumn + }; + libConfigPlainGalleryGrid: PlainLibConfig = { + plainGalleryConfig: this.plainGalleryGrid + }; + + openImageModalRow(id: number, image: Image): void { + console.log('Opening modal gallery from custom plain gallery row, with image: ', image); + const index: number = this.getCurrentIndexCustomLayout(image, this.images); + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: this.images, + currentImage: this.images[index] + }) as ModalGalleryRef; + } + + openImageModalColumn(id: number, image: Image): void { + console.log('Opening modal gallery from custom plain gallery column, with image: ', image); + const index: number = this.getCurrentIndexCustomLayout(image, this.images); + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: this.images, + currentImage: this.images[index] + }) as ModalGalleryRef; + } + + openImageModalRowDescription(id: number, image: Image): void { + console.log('Opening modal gallery from custom plain gallery row and description, with image: ', image); + const index: number = this.getCurrentIndexCustomLayout(image, this.imagesRect); + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images: this.imagesRect, + currentImage: this.imagesRect[index] + }) as ModalGalleryRef; + } + + addRandomImage(): void { + // add to images array + const imageToCopy: Image = this.images[Math.floor(Math.random() * this.images.length)]; + const newImage: Image = new Image(this.images.length - 1 + 1, imageToCopy.modal, imageToCopy.plain); + this.images = [...this.images, newImage]; + // add also to imagesRect + const imageRectToCopy: Image = this.imagesRect[Math.floor(Math.random() * this.imagesRect.length)]; + const newImageRect: Image = new Image(this.imagesRect.length - 1 + 1, imageRectToCopy.modal, imageRectToCopy.plain); + this.imagesRect = [...this.imagesRect, newImageRect]; + } + + onShow(id: number, index: number, images: Image[] = this.images): void { + const dialogRef: ModalGalleryRef = this.modalGalleryService.open({ + id, + images, + currentImage: images[index] + }) as ModalGalleryRef; + } + + trackById(index: number, item: Image): number { + return item.id; + } + + private getCurrentIndexCustomLayout(image: Image, images: Image[]): number { + return image ? images.indexOf(image) : -1; + } +} diff --git a/src/app/plain-gallery/plain-gallery.html b/src/app/plain-gallery/plain-gallery.html new file mode 100644 index 00000000..73f06879 --- /dev/null +++ b/src/app/plain-gallery/plain-gallery.html @@ -0,0 +1,152 @@ +

Plain Gallery

+
+ +

If you want, you can add a random image to every example + +

+
+
+

Layout examples

+
+

P1 - (id=200) - row plain gallery layout (limit 2) and custom size

+
+ +
+
+
+

P2 - (id=201) - row plain gallery layout space around (limit 2)

+
+ +
+
+
+

P3 - (id=202) - row plain gallery layout with a tags and custom rectangular sizes (limit 4)

+
+ +
+
+
+

P4 - (id=203) - column plain gallery layout (limit 3)

+
+ +
+
+
+

P5 - (id=204) - grid plain gallery layout and custom size

+
+ +
+
+
+

P6 - (id=205) - full custom plain gallery (row) with image pointer

+
+
+ + + +
+
+
+
+

P7 - (id=206) - full custom plain gallery (column) with image pointer

+
+
+ + + +
+
+
+
+

P8 - (id=207) - full custom plain gallery (row) with descriptions

+
+
+ +
+ +
{{img.modal.description ? img.modal.description : 'No description available'}} +
+
+
+
+
+
+
+

P9 - (id=208) - row plain gallery layout with fallback images when it's not possible to load normal images (to fix issue #194)

+
+ +
+
+
+

P10 - (id=209) - row plain gallery layout with a tags and custom rectangular sizes (limit 4) + fallback images when it's not possible to load normal images (to fix issue #194)

+
+ +
+
+
+

P11 - (id=210) - row plain gallery layout (limit 2) and custom size + remove title attribute on images

+
+ +
+
+
+

P12 - (id=211) - row plain gallery layout with an empty images array

+
+ +
+
+
diff --git a/src/app/plain-gallery/plain-gallery.scss b/src/app/plain-gallery/plain-gallery.scss new file mode 100644 index 00000000..b498df8d --- /dev/null +++ b/src/app/plain-gallery/plain-gallery.scss @@ -0,0 +1,169 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +:host { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + margin-left: 20px; + margin-right: 20px; +} + +section { + width: 100%; +} + +$text-color: #fff; +$background: rgba(0, 0, 0, .7); + +button { + background-color: #0060b7; + color: white; + height: 25px; + width: auto; + border: 0; + border-radius: 5px; + cursor: pointer; + + &:hover { + background-color: #0086ff; + } +} + +.my-app-custom-plain-container-row { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + .my-app-custom-image-row { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-column { + align-items: center; + display: flex; + flex-direction: column; + justify-content: flex-start; + + .my-app-custom-image-column { + cursor: pointer; + height: auto; + margin-right: 2px; + width: 50px; + + &.after { + border-top: 2px; + cursor: pointer; + display: none; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + +.my-app-custom-plain-container-with-desc { + align-items: center; + display: flex; + flex-direction: row; + justify-content: flex-start; + + figure { + margin: 0; + position: relative; + + img { + max-width: 100%; + height: auto; + cursor: pointer; + } + + figcaption { + background: rgba(0, 0, 0, .5); + color: #fff; + font-size: 85%; + padding: 5px; + position: absolute; + bottom: 3px; + left: 0; + right: 0; + } + } + + .description { + font-weight: bold; + text-align: center; + } + + .my-app-custom-image-with-desc { + height: auto; + margin-right: 2px; + width: 200px; + align-self: start; + } +} + +.more { + background: $background; + cursor: pointer; + color: $text-color; + padding-top: 4px; + height: 46px; + position: absolute; + text-align: center; + width: 50px; +} + + +.transcluded { + color: white; + font-weight: 600; + font-size: 24px; + text-align: center; + position: absolute; + top: 50%; + width: 100%; + pointer-events: none; +} + +.title { + margin-top: 40px; +} diff --git a/src/assets/images/gallery/fallback-carousel1.jpg b/src/assets/images/gallery/fallback-carousel1.jpg new file mode 100644 index 00000000..5d49263f Binary files /dev/null and b/src/assets/images/gallery/fallback-carousel1.jpg differ diff --git a/src/assets/images/gallery/fallback-carousel2.jpg b/src/assets/images/gallery/fallback-carousel2.jpg new file mode 100644 index 00000000..2c2ce26a Binary files /dev/null and b/src/assets/images/gallery/fallback-carousel2.jpg differ diff --git a/src/assets/images/gallery/fallback-carousel3.jpg b/src/assets/images/gallery/fallback-carousel3.jpg new file mode 100644 index 00000000..a4ea6b40 Binary files /dev/null and b/src/assets/images/gallery/fallback-carousel3.jpg differ diff --git a/src/assets/images/gallery/fallback-carousel4.jpg b/src/assets/images/gallery/fallback-carousel4.jpg new file mode 100644 index 00000000..0d59507d Binary files /dev/null and b/src/assets/images/gallery/fallback-carousel4.jpg differ diff --git a/src/assets/images/gallery/fallback-carousel5.jpg b/src/assets/images/gallery/fallback-carousel5.jpg new file mode 100644 index 00000000..5511feb8 Binary files /dev/null and b/src/assets/images/gallery/fallback-carousel5.jpg differ diff --git a/src/assets/images/gallery/fallback1.jpg b/src/assets/images/gallery/fallback1.jpg new file mode 100644 index 00000000..0827c782 Binary files /dev/null and b/src/assets/images/gallery/fallback1.jpg differ diff --git a/src/assets/images/gallery/fallback2.jpg b/src/assets/images/gallery/fallback2.jpg new file mode 100644 index 00000000..6562c517 Binary files /dev/null and b/src/assets/images/gallery/fallback2.jpg differ diff --git a/src/assets/images/gallery/fallback3.jpg b/src/assets/images/gallery/fallback3.jpg new file mode 100644 index 00000000..3a3d63f4 Binary files /dev/null and b/src/assets/images/gallery/fallback3.jpg differ diff --git a/src/assets/images/gallery/fallback4.jpg b/src/assets/images/gallery/fallback4.jpg new file mode 100644 index 00000000..0dfe8551 Binary files /dev/null and b/src/assets/images/gallery/fallback4.jpg differ diff --git a/src/assets/images/gallery/fallback5.jpg b/src/assets/images/gallery/fallback5.jpg new file mode 100644 index 00000000..38da58e4 Binary files /dev/null and b/src/assets/images/gallery/fallback5.jpg differ diff --git a/src/assets/images/gallery/img1.jpg b/src/assets/images/gallery/img1.jpg new file mode 100644 index 00000000..7d358899 Binary files /dev/null and b/src/assets/images/gallery/img1.jpg differ diff --git a/src/assets/images/gallery/img2.jpg b/src/assets/images/gallery/img2.jpg new file mode 100644 index 00000000..4c101c12 Binary files /dev/null and b/src/assets/images/gallery/img2.jpg differ diff --git a/src/assets/images/gallery/img2.png b/src/assets/images/gallery/img2.png new file mode 100644 index 00000000..295cb1f4 Binary files /dev/null and b/src/assets/images/gallery/img2.png differ diff --git a/src/assets/images/gallery/img3.jpg b/src/assets/images/gallery/img3.jpg new file mode 100644 index 00000000..c6b1c22d Binary files /dev/null and b/src/assets/images/gallery/img3.jpg differ diff --git a/src/assets/images/gallery/img4.jpg b/src/assets/images/gallery/img4.jpg new file mode 100644 index 00000000..403482ae Binary files /dev/null and b/src/assets/images/gallery/img4.jpg differ diff --git a/src/assets/images/gallery/img5.jpg b/src/assets/images/gallery/img5.jpg new file mode 100644 index 00000000..bf97ab6c Binary files /dev/null and b/src/assets/images/gallery/img5.jpg differ diff --git a/src/assets/images/gallery/milan-pegasus-gallery-statue-1024w.jpg b/src/assets/images/gallery/milan-pegasus-gallery-statue-1024w.jpg new file mode 100644 index 00000000..c0a922d1 Binary files /dev/null and b/src/assets/images/gallery/milan-pegasus-gallery-statue-1024w.jpg differ diff --git a/src/assets/images/gallery/milan-pegasus-gallery-statue-480w.jpg b/src/assets/images/gallery/milan-pegasus-gallery-statue-480w.jpg new file mode 100644 index 00000000..ac54d7d7 Binary files /dev/null and b/src/assets/images/gallery/milan-pegasus-gallery-statue-480w.jpg differ diff --git a/src/assets/images/gallery/milan-pegasus-gallery-statue-768w.jpg b/src/assets/images/gallery/milan-pegasus-gallery-statue-768w.jpg new file mode 100644 index 00000000..dba50163 Binary files /dev/null and b/src/assets/images/gallery/milan-pegasus-gallery-statue-768w.jpg differ diff --git a/src/assets/images/gallery/milan-pegasus-gallery-statue.jpg b/src/assets/images/gallery/milan-pegasus-gallery-statue.jpg new file mode 100644 index 00000000..f2c02760 Binary files /dev/null and b/src/assets/images/gallery/milan-pegasus-gallery-statue.jpg differ diff --git a/src/assets/images/gallery/pexels-photo-135230-1024w.png b/src/assets/images/gallery/pexels-photo-135230-1024w.png new file mode 100644 index 00000000..a543d4db Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-135230-1024w.png differ diff --git a/src/assets/images/gallery/pexels-photo-135230-480w.png b/src/assets/images/gallery/pexels-photo-135230-480w.png new file mode 100644 index 00000000..dc29041e Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-135230-480w.png differ diff --git a/src/assets/images/gallery/pexels-photo-135230-768w.png b/src/assets/images/gallery/pexels-photo-135230-768w.png new file mode 100644 index 00000000..b04917ed Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-135230-768w.png differ diff --git a/src/assets/images/gallery/pexels-photo-135230.png b/src/assets/images/gallery/pexels-photo-135230.png new file mode 100644 index 00000000..8aa887fd Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-135230.png differ diff --git a/src/assets/images/gallery/pexels-photo-47223-1024w.jpeg b/src/assets/images/gallery/pexels-photo-47223-1024w.jpeg new file mode 100644 index 00000000..f7931c21 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-47223-1024w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-47223-480w.jpeg b/src/assets/images/gallery/pexels-photo-47223-480w.jpeg new file mode 100644 index 00000000..14897ecf Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-47223-480w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-47223-768w.jpeg b/src/assets/images/gallery/pexels-photo-47223-768w.jpeg new file mode 100644 index 00000000..73f72c9a Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-47223-768w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-47223.jpeg b/src/assets/images/gallery/pexels-photo-47223.jpeg new file mode 100644 index 00000000..46ea1f75 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-47223.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-52062-1024w.jpeg b/src/assets/images/gallery/pexels-photo-52062-1024w.jpeg new file mode 100644 index 00000000..a7052fd3 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-52062-1024w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-52062-480w.jpeg b/src/assets/images/gallery/pexels-photo-52062-480w.jpeg new file mode 100644 index 00000000..1ac7ce8c Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-52062-480w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-52062-768w.jpeg b/src/assets/images/gallery/pexels-photo-52062-768w.jpeg new file mode 100644 index 00000000..e1f3256c Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-52062-768w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-52062.jpeg b/src/assets/images/gallery/pexels-photo-52062.jpeg new file mode 100644 index 00000000..0c9502e4 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-52062.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-547115-1024w.jpeg b/src/assets/images/gallery/pexels-photo-547115-1024w.jpeg new file mode 100644 index 00000000..592a1516 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-547115-1024w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-547115-480w.jpeg b/src/assets/images/gallery/pexels-photo-547115-480w.jpeg new file mode 100644 index 00000000..15c404dd Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-547115-480w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-547115-768w.jpeg b/src/assets/images/gallery/pexels-photo-547115-768w.jpeg new file mode 100644 index 00000000..68fa15da Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-547115-768w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-547115.jpeg b/src/assets/images/gallery/pexels-photo-547115.jpeg new file mode 100644 index 00000000..4056b197 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-547115.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-556664-1024w.jpeg b/src/assets/images/gallery/pexels-photo-556664-1024w.jpeg new file mode 100644 index 00000000..b56cf006 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-556664-1024w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-556664-480w.jpeg b/src/assets/images/gallery/pexels-photo-556664-480w.jpeg new file mode 100644 index 00000000..f7990e34 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-556664-480w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-556664-768w.jpeg b/src/assets/images/gallery/pexels-photo-556664-768w.jpeg new file mode 100644 index 00000000..cbb74582 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-556664-768w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-556664.jpeg b/src/assets/images/gallery/pexels-photo-556664.jpeg new file mode 100644 index 00000000..33383d36 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-556664.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-66943-1024w.jpeg b/src/assets/images/gallery/pexels-photo-66943-1024w.jpeg new file mode 100644 index 00000000..18988bf3 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-66943-1024w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-66943-480w.jpeg b/src/assets/images/gallery/pexels-photo-66943-480w.jpeg new file mode 100644 index 00000000..c40829b9 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-66943-480w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-66943-768w.jpeg b/src/assets/images/gallery/pexels-photo-66943-768w.jpeg new file mode 100644 index 00000000..953ef6f3 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-66943-768w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-66943.jpeg b/src/assets/images/gallery/pexels-photo-66943.jpeg new file mode 100644 index 00000000..8dd20157 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-66943.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-787594-1024w.jpeg b/src/assets/images/gallery/pexels-photo-787594-1024w.jpeg new file mode 100644 index 00000000..52113fef Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-787594-1024w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-787594-480w.jpeg b/src/assets/images/gallery/pexels-photo-787594-480w.jpeg new file mode 100644 index 00000000..3b97fb45 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-787594-480w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-787594-768w.jpeg b/src/assets/images/gallery/pexels-photo-787594-768w.jpeg new file mode 100644 index 00000000..b08cc133 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-787594-768w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-787594.jpeg b/src/assets/images/gallery/pexels-photo-787594.jpeg new file mode 100644 index 00000000..e2986131 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-787594.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-803105-1024w.jpeg b/src/assets/images/gallery/pexels-photo-803105-1024w.jpeg new file mode 100644 index 00000000..99bb60cd Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-803105-1024w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-803105-480w.jpeg b/src/assets/images/gallery/pexels-photo-803105-480w.jpeg new file mode 100644 index 00000000..815624dc Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-803105-480w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-803105-768w.jpeg b/src/assets/images/gallery/pexels-photo-803105-768w.jpeg new file mode 100644 index 00000000..1118cde8 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-803105-768w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-803105.jpeg b/src/assets/images/gallery/pexels-photo-803105.jpeg new file mode 100644 index 00000000..8b7c44a4 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-803105.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-93750-1024w.jpeg b/src/assets/images/gallery/pexels-photo-93750-1024w.jpeg new file mode 100644 index 00000000..bf1e8eaf Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-93750-1024w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-93750-480w.jpeg b/src/assets/images/gallery/pexels-photo-93750-480w.jpeg new file mode 100644 index 00000000..08020dbe Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-93750-480w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-93750-768w.jpeg b/src/assets/images/gallery/pexels-photo-93750-768w.jpeg new file mode 100644 index 00000000..8fe37d40 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-93750-768w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-93750.jpeg b/src/assets/images/gallery/pexels-photo-93750.jpeg new file mode 100644 index 00000000..ab537b02 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-93750.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-94420-1024w.jpeg b/src/assets/images/gallery/pexels-photo-94420-1024w.jpeg new file mode 100644 index 00000000..c8a13148 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-94420-1024w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-94420-480w.jpeg b/src/assets/images/gallery/pexels-photo-94420-480w.jpeg new file mode 100644 index 00000000..acc790e7 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-94420-480w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-94420-768w.jpeg b/src/assets/images/gallery/pexels-photo-94420-768w.jpeg new file mode 100644 index 00000000..11fbaad9 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-94420-768w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-94420.jpeg b/src/assets/images/gallery/pexels-photo-94420.jpeg new file mode 100644 index 00000000..d3ebb012 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-94420.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-96947-1024w.jpeg b/src/assets/images/gallery/pexels-photo-96947-1024w.jpeg new file mode 100644 index 00000000..3e4a701f Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-96947-1024w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-96947-480w.jpeg b/src/assets/images/gallery/pexels-photo-96947-480w.jpeg new file mode 100644 index 00000000..0248070f Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-96947-480w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-96947-768w.jpeg b/src/assets/images/gallery/pexels-photo-96947-768w.jpeg new file mode 100644 index 00000000..c74f523e Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-96947-768w.jpeg differ diff --git a/src/assets/images/gallery/pexels-photo-96947.jpeg b/src/assets/images/gallery/pexels-photo-96947.jpeg new file mode 100644 index 00000000..c6965748 Binary files /dev/null and b/src/assets/images/gallery/pexels-photo-96947.jpeg differ diff --git a/src/assets/images/gallery/thumbs/fallback-carousel1.jpg b/src/assets/images/gallery/thumbs/fallback-carousel1.jpg new file mode 100644 index 00000000..5ce2a4ed Binary files /dev/null and b/src/assets/images/gallery/thumbs/fallback-carousel1.jpg differ diff --git a/src/assets/images/gallery/thumbs/fallback-carousel2.jpg b/src/assets/images/gallery/thumbs/fallback-carousel2.jpg new file mode 100644 index 00000000..6417a30b Binary files /dev/null and b/src/assets/images/gallery/thumbs/fallback-carousel2.jpg differ diff --git a/src/assets/images/gallery/thumbs/fallback-carousel3.jpg b/src/assets/images/gallery/thumbs/fallback-carousel3.jpg new file mode 100644 index 00000000..a0939a7a Binary files /dev/null and b/src/assets/images/gallery/thumbs/fallback-carousel3.jpg differ diff --git a/src/assets/images/gallery/thumbs/fallback-carousel4.jpg b/src/assets/images/gallery/thumbs/fallback-carousel4.jpg new file mode 100644 index 00000000..5be118b7 Binary files /dev/null and b/src/assets/images/gallery/thumbs/fallback-carousel4.jpg differ diff --git a/src/assets/images/gallery/thumbs/fallback-carousel5.jpg b/src/assets/images/gallery/thumbs/fallback-carousel5.jpg new file mode 100644 index 00000000..c61eb0ee Binary files /dev/null and b/src/assets/images/gallery/thumbs/fallback-carousel5.jpg differ diff --git a/src/assets/images/gallery/thumbs/fallback1.jpg b/src/assets/images/gallery/thumbs/fallback1.jpg new file mode 100644 index 00000000..2afb5530 Binary files /dev/null and b/src/assets/images/gallery/thumbs/fallback1.jpg differ diff --git a/src/assets/images/gallery/thumbs/fallback2.jpg b/src/assets/images/gallery/thumbs/fallback2.jpg new file mode 100644 index 00000000..140e9718 Binary files /dev/null and b/src/assets/images/gallery/thumbs/fallback2.jpg differ diff --git a/src/assets/images/gallery/thumbs/fallback3.jpg b/src/assets/images/gallery/thumbs/fallback3.jpg new file mode 100644 index 00000000..11115387 Binary files /dev/null and b/src/assets/images/gallery/thumbs/fallback3.jpg differ diff --git a/src/assets/images/gallery/thumbs/fallback4.jpg b/src/assets/images/gallery/thumbs/fallback4.jpg new file mode 100644 index 00000000..9737793b Binary files /dev/null and b/src/assets/images/gallery/thumbs/fallback4.jpg differ diff --git a/src/assets/images/gallery/thumbs/fallback5.jpg b/src/assets/images/gallery/thumbs/fallback5.jpg new file mode 100644 index 00000000..88915773 Binary files /dev/null and b/src/assets/images/gallery/thumbs/fallback5.jpg differ diff --git a/src/assets/images/gallery/thumbs/img1.jpg b/src/assets/images/gallery/thumbs/img1.jpg new file mode 100644 index 00000000..68e10d14 Binary files /dev/null and b/src/assets/images/gallery/thumbs/img1.jpg differ diff --git a/src/assets/images/gallery/thumbs/img2.jpg b/src/assets/images/gallery/thumbs/img2.jpg new file mode 100644 index 00000000..3b69746a Binary files /dev/null and b/src/assets/images/gallery/thumbs/img2.jpg differ diff --git a/src/assets/images/gallery/thumbs/img3.png b/src/assets/images/gallery/thumbs/img3.png new file mode 100644 index 00000000..3f0bf060 Binary files /dev/null and b/src/assets/images/gallery/thumbs/img3.png differ diff --git a/src/assets/images/gallery/thumbs/img4.jpg b/src/assets/images/gallery/thumbs/img4.jpg new file mode 100644 index 00000000..d08ebe7f Binary files /dev/null and b/src/assets/images/gallery/thumbs/img4.jpg differ diff --git a/src/assets/images/gallery/thumbs/img5.jpg b/src/assets/images/gallery/thumbs/img5.jpg new file mode 100644 index 00000000..b932ee9f Binary files /dev/null and b/src/assets/images/gallery/thumbs/img5.jpg differ diff --git a/src/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg b/src/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg new file mode 100644 index 00000000..6881e08c Binary files /dev/null and b/src/assets/images/gallery/thumbs/t-milan-pegasus-gallery-statue.jpg differ diff --git a/src/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg b/src/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg new file mode 100644 index 00000000..be93d546 Binary files /dev/null and b/src/assets/images/gallery/thumbs/t-pexels-photo-47223.jpg differ diff --git a/src/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg b/src/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg new file mode 100644 index 00000000..eb99fe42 Binary files /dev/null and b/src/assets/images/gallery/thumbs/t-pexels-photo-52062.jpg differ diff --git a/src/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg b/src/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg new file mode 100644 index 00000000..e33dc4be Binary files /dev/null and b/src/assets/images/gallery/thumbs/t-pexels-photo-66943.jpg differ diff --git a/src/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg b/src/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg new file mode 100644 index 00000000..feae47af Binary files /dev/null and b/src/assets/images/gallery/thumbs/t-pexels-photo-93750.jpg differ diff --git a/src/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg b/src/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg new file mode 100644 index 00000000..075cdd51 Binary files /dev/null and b/src/assets/images/gallery/thumbs/t-pexels-photo-94420.jpg differ diff --git a/src/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg b/src/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg new file mode 100644 index 00000000..ab777557 Binary files /dev/null and b/src/assets/images/gallery/thumbs/t-pexels-photo-96947.jpg differ diff --git a/src/assets/images/loading-spinner-samples/pexels-photo-106006-thumb.jpg b/src/assets/images/loading-spinner-samples/pexels-photo-106006-thumb.jpg new file mode 100644 index 00000000..e80e1a53 Binary files /dev/null and b/src/assets/images/loading-spinner-samples/pexels-photo-106006-thumb.jpg differ diff --git a/src/assets/images/loading-spinner-samples/pexels-photo-106006.jpg b/src/assets/images/loading-spinner-samples/pexels-photo-106006.jpg new file mode 100644 index 00000000..6baa8325 Binary files /dev/null and b/src/assets/images/loading-spinner-samples/pexels-photo-106006.jpg differ diff --git a/src/assets/images/loading-spinner-samples/pexels-photo-464336-thumb.jpg b/src/assets/images/loading-spinner-samples/pexels-photo-464336-thumb.jpg new file mode 100644 index 00000000..7bd64447 Binary files /dev/null and b/src/assets/images/loading-spinner-samples/pexels-photo-464336-thumb.jpg differ diff --git a/src/assets/images/loading-spinner-samples/pexels-photo-464336.jpg b/src/assets/images/loading-spinner-samples/pexels-photo-464336.jpg new file mode 100644 index 00000000..c7253d57 Binary files /dev/null and b/src/assets/images/loading-spinner-samples/pexels-photo-464336.jpg differ diff --git a/src/assets/images/loading-spinner-samples/pexels-photo-74506-thumb.jpg b/src/assets/images/loading-spinner-samples/pexels-photo-74506-thumb.jpg new file mode 100644 index 00000000..24028aa0 Binary files /dev/null and b/src/assets/images/loading-spinner-samples/pexels-photo-74506-thumb.jpg differ diff --git a/src/assets/images/loading-spinner-samples/pexels-photo-74506.jpg b/src/assets/images/loading-spinner-samples/pexels-photo-74506.jpg new file mode 100644 index 00000000..c4973505 Binary files /dev/null and b/src/assets/images/loading-spinner-samples/pexels-photo-74506.jpg differ diff --git a/src/assets/images/loading-spinner-samples/pexels-photo-thumb.jpg b/src/assets/images/loading-spinner-samples/pexels-photo-thumb.jpg new file mode 100644 index 00000000..34615206 Binary files /dev/null and b/src/assets/images/loading-spinner-samples/pexels-photo-thumb.jpg differ diff --git a/src/assets/images/loading-spinner-samples/pexels-photo.jpg b/src/assets/images/loading-spinner-samples/pexels-photo.jpg new file mode 100644 index 00000000..3ceffcbe Binary files /dev/null and b/src/assets/images/loading-spinner-samples/pexels-photo.jpg differ diff --git a/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891-thumb.jpg b/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891-thumb.jpg new file mode 100644 index 00000000..8cfda5fa Binary files /dev/null and b/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891-thumb.jpg differ diff --git a/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891.jpg b/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891.jpg new file mode 100644 index 00000000..9457c1c6 Binary files /dev/null and b/src/assets/images/loading-spinner-samples/traffic-highway-lights-night-56891.jpg differ diff --git a/src/assets/menu.svg b/src/assets/menu.svg new file mode 100644 index 00000000..65fc9003 --- /dev/null +++ b/src/assets/menu.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/favicon.png b/src/favicon.png new file mode 100644 index 00000000..4e279875 Binary files /dev/null and b/src/favicon.png differ diff --git a/src/index.html b/src/index.html new file mode 100644 index 00000000..475fb312 --- /dev/null +++ b/src/index.html @@ -0,0 +1,18 @@ + + + + + @ks89/angular-modal-gallery demo + + + + + + + + + + + diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 00000000..1d335a67 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,8 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule, { + ngZoneEventCoalescing: true +}) + .catch(err => console.error(err)); diff --git a/src/styles.scss b/src/styles.scss new file mode 100644 index 00000000..47d84e5a --- /dev/null +++ b/src/styles.scss @@ -0,0 +1,61 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017-2024 Stefano Cappa (Ks89) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// You can add global styles to this file, and also import other style files + +// ***************************************************************** +// *********** required by @ks89/angular-modal-gallery ************* +// ***************************************************************** +// ATTENTION: You have to install @angular/cdk to be able to use @ks89/angular-modal-gallery properly +@import "@angular/cdk/overlay-prebuilt.css"; + +.ks-modal-gallery-backdrop { + background: #000 !important;; + opacity: 0.85 !important;; +} + +.ks-modal-gallery-panel { + z-index: 90000 !important; +} +// ***************************************************************** +// ***************************************************************** +// ***************************************************************** + +body { + font-family: "Montserrat", sans-serif; + margin: 0; + padding: 0; +} + +// Not required by angular-modal-gallery. Used only in this demo +.red-text { + color: red; +} + +.title { + text-align: center; + color: red; +} + +.center-text { + text-align: center; +} diff --git a/src/test.ts b/src/test.ts new file mode 100644 index 00000000..c04c8760 --- /dev/null +++ b/src/test.ts @@ -0,0 +1,26 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/testing'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +declare const require: { + context(path: string, deep?: boolean, filter?: RegExp): { + (id: string): T; + keys(): string[]; + }; +}; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting(), +); + +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().forEach(context); diff --git a/systemjs.config.js b/systemjs.config.js deleted file mode 100644 index 2e12bf6a..00000000 --- a/systemjs.config.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * System configuration for Angular 2 samples - * Adjust as necessary for your application needs. - */ -(function(global) { - // map tells the System loader where to look for things - var map = { - 'app': '/app', // 'dist', -// 'httpresource': 'node_modules/httpresource', - '@angular': 'node_modules/@angular', - 'rxjs': 'node_modules/rxjs', - 'directives' : 'directives/' - }; - // packages tells the System loader how to load when no filename and/or no extension - var packages = { - 'app': { main: 'main.js', defaultExtension: 'js' }, - 'rxjs': { defaultExtension: 'js' }, - 'directives':{ defaultExtension: 'js' } - }; - var ngPackageNames = [ - 'common', - 'compiler', - 'core', - 'platform-browser', - 'platform-browser-dynamic', - 'upgrade' - ]; - // Individual files (~300 requests): - function packIndex(pkgName) { - packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' }; - } - // Bundled (~40 requests): - function packUmd(pkgName) { - packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' }; - } - // Most environments should use UMD; some (Karma) need the individual index files - var setPackageConfig = System.packageWithIndex ? packIndex : packUmd; -// packages['httpresource']={ default: 'resource.js',defaultExtension: 'js' }; - // Add package entries for angular packages - ngPackageNames.forEach(setPackageConfig); - var config = { - map: map, - packages: packages - }; - System.config(config); -})(this); diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 00000000..3775b37e --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/tsconfig.json b/tsconfig.json index 9be71e4c..0b8ea91d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,17 +1,42 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { + "compileOnSave": false, "compilerOptions": { - "target": "es5", - "module": "system", - "moduleResolution": "node", - "sourceMap": true, - "emitDecoratorMetadata": true, + "paths": { + "@ks89/angular-modal-gallery": [ + "./dist/ks89/angular-modal-gallery" + ] + }, + "outDir": "./dist/out-tsc", + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": false, // FIXME should become tre + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "isolatedModules": true, + "esModuleInterop": true, "experimentalDecorators": true, - "removeComments": false, - "noImplicitAny": false + "moduleResolution": "bundler", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "useDefineForClassFields": false, // to inject sanitizer without errors + "lib": [ + "ES2022", + "dom" + ], + "typeRoots": [ + "node_modules/@types" + ] }, - "exclude": [ - "node_modules", - "typings/main", - "typings/main.d.ts" - ] + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + + // FIXME THIS SHOULD BE FORCED TO TRUE IN THE FUTURE VERSIONS OF THE LIBRARY + "strictTemplates": false + } } diff --git a/tsconfig.spec.json b/tsconfig.spec.json new file mode 100644 index 00000000..5fb748d9 --- /dev/null +++ b/tsconfig.spec.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/typings.json b/typings.json deleted file mode 100644 index c06bb4d7..00000000 --- a/typings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "ambientDependencies": { - "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#7de6c3dd94feaeb21f20054b9f30d5dabc5efabd", - "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#7de6c3dd94feaeb21f20054b9f30d5dabc5efabd" - } -}