diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml new file mode 100644 index 0000000..1a5a978 --- /dev/null +++ b/.github/workflows/nodejs.yml @@ -0,0 +1,42 @@ +# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node + +name: Node.js CI + +on: + push: + branches: [ master, '[0-9]+.[0-9]+.x' ] + pull_request: + branches: [ master, '[0-9]+.[0-9]+.x' ] + +jobs: + run-tests: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [20.x, 22.x] + + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + - name: Install packages + run: npm ci + - name: Install Playwright + run: npx playwright install --with-deps --only-shell chromium + - name: Lint + run: npm run lint + - name: Build Core & Resources + run: npm run build + - name: Test + run: npm run test + - name: Publish to coveralls.io + if: github.repository == 'IgniteUI/igniteui-i18n' && matrix.node-version == '20.x' + uses: coverallsapp/github-action@v2.3.4 + with: + github-token: ${{ github.token }} diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 185208c..2de4119 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -27,21 +27,37 @@ jobs: - name: Build the package run: npm run build - - name: Version the package + - name: Set peer dependency versions for core package + shell: pwsh + run: | + $pattern = '"igniteui-i18n-resources": "\S?(?(\d\S?)+)"' + $filePath = "dist/igniteui-i18n-core/package.json" + (Get-Content -Path $filePath -Raw) -replace $pattern, "`"igniteui-i18n-resources`": `"$env:VERSION`"" | Set-Content $filePath + Write-Output (Get-Content -Path $filePath -Raw) + + - name: Version the core package run: npm version ${VERSION} --no-git-tag-version --save --verbose working-directory: dist/igniteui-i18n-core - - name: Publish the package + - name: Publish the core package run: npm publish --tag ${NPM_TAG} working-directory: dist/igniteui-i18n-core env: NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} - - name: Version the package + - name: Set dependency versions for resource package + shell: pwsh + run: | + $pattern = '"igniteui-i18n-core": "\S?(?(\d\S?)+)"' + $filePath = "dist/igniteui-i18n-resources/package.json" + (Get-Content -Path $filePath -Raw) -replace $pattern, "`"igniteui-i18n-core`": `"$env:VERSION`"" | Set-Content $filePath + Write-Output (Get-Content -Path $filePath -Raw) + + - name: Version the resources package run: npm version ${VERSION} --no-git-tag-version --save --verbose working-directory: dist/igniteui-i18n-resources - - name: Publish the package + - name: Publish the resources package run: npm publish --tag ${NPM_TAG} working-directory: dist/igniteui-i18n-resources env: diff --git a/.gitignore b/.gitignore index 9a5aced..413e556 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,11 @@ +# IDE - VSCode/VS +.vscode/* +.vs/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + # Logs logs *.log @@ -137,3 +145,10 @@ dist # Vite logs files vite.config.js.timestamp-* vite.config.ts.timestamp-* + + +# compiled output +/dist +/tmp +/out-tsc +/test-results diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..1f6c6e3 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,7 @@ +dist +coverage +test-results +package-lock.json +*.min.* +*.yml +*.md \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..231cf57 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,17 @@ +{ + "tabWidth": 4, + "singleQuote": true, + "trailingComma": "none", + "printWidth": 120, + "endOfLine": "auto", + "overrides": [ + { + "files": ["*.json", "*.mjs"], + "options": { + "tabWidth": 2, + "singleQuote": false, + "trailingComma": "es5" + } + } + ] +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..95e4c3e --- /dev/null +++ b/LICENSE @@ -0,0 +1,16 @@ +This is a commercial product, requiring a valid paid-for license for commercial use. +This product is free to use for non-commercial educational use for students in K through 12 grades +or University programs, and for educators to use in a classroom setting as examples / tools in their curriculum. + +In order for us to verify your eligibility for free usage, please register for trial at +https://Infragistics.com/Angular and open a support ticket with a request for free license. + +To acquire a license for commercial usage, please register for trial at https://Infragistics.com/Angular +and refer to the purchasing options in the pricing section on the product page. + +This repository includes code originally copied from https://github.com/zloirock/core-js +in the projects/igniteui-angular/src/lib/core/setImmediate.ts file. The original version of the code is MIT licensed. See the file header for details. + +© Copyright 2020 INFRAGISTICS. All Rights Reserved. +The Infragistics Ultimate license & copyright applies to this distribution. +For information on that license, please go to our website https://www.infragistics.com/legal/license. diff --git a/README.md b/README.md index 6ba3b2a..453b03c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,103 @@ -# igniteui-i18n-core -Ignite UI Internationalization packages, containing localization functionality, translation resources and locale formatting. +

+ Ignite UI Localization - from Infragistics +

+ +![Node.js CI](https://github.com/IgniteUI/igniteui-i18n/workflows/Node.js%20CI/badge.svg) +[![Coverage Status](https://coveralls.io/repos/github/IgniteUI/igniteui-i18n/badge.svg?branch=master)](https://coveralls.io/github/IgniteUI/igniteui-i18n?branch=master) +[![npm version](https://badge.fury.io/js/igniteui-i18n.svg)](https://badge.fury.io/js/igniteui-i18n) + +The Ignite UI i18n repository provides localized strings and locale formatting to all Ignite UI products and components. The core package provides the functionality for locale and resource strings management, while the resources package provides localized resource strings for each currently supported language by Ignite UI. Both combined gives a unified and easy way of setting desired language or locale for the Ignite UI components globally and individually for each component. + +## Setup + +To setup the repo for local work run: + +``` +npm install +``` + +## Building + +To build all packages run: + +``` +npm run build +``` + +To build just the core package run: + +``` +npm run build:core +``` + +To build just the resources package run: + +``` +npm run build:resources +``` + +## Lint + +The repo follows coding guidelines, which are kept in check using lint. To run it locally run: + +``` +npm run lint +``` + +For any prettier errors make sure to run the `pretty:fix` command, as it should address most of the issues. For easier you can use the [`Prettier plugin`](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) and enable `editor.formatOnSave` setting. + +## Tests + +The repo uses [Vitest](https://vitest.dev/guide/) for a base testing framework and [Playwright](https://vitest.dev/guide/browser/playwright.html) for in browser testing. Also the ability for out of browser testing is available using [jsdom](https://github.com/jsdom/jsdom). It is highly encouraged to use the native browser one, while the other can be used for easier debugging of tests and core functionality, but keep in might the nature of `jsdom` not being a native browser. + +If you are using `VSCode`, I recommend to install the [Vitest extension](https://marketplace.visualstudio.com/items?itemName=vitest.explorer) as well, otherwise debugging using `Javscript Debug Console` does not work for me as expected and the source maps are not correct. Maybe its a config issue, but using the plugin is easier anyway for debugging. + +To run the tests run: + +``` +npm run test +``` + +If you use Playwright for the first time it will throw an error. Just install the necessary dependencies using: + +``` +npx playwright install --with-deps --only-shell chromium +``` + +By default the tests run in `headless` mode using `Chromium`. If you would like to see it in the browser itself you need to set [headless](https://vitest.dev/guide/browser/config.html#browser-headless) option in the `vitest.browser.config.ts` file for the desired browser: + +``` +test: { + browser: { + headless: false + } +} +``` + +To run a specific test, set in the test source `only` option for a test in the following way: + +```typescript +it('should test something', { only: true }, () => { + // Test code +}); +``` + +The following way should also work (but not for me :s ): + +```typescript +it.only('should test something', () => { + // Test code +}); +``` + +## License + +This is a commercial product, requiring a valid paid-for license for commercial use. +This product is free to use for non-commercial educational use for students in K through 12 grades or University programs, and for educators to use in a classroom setting as examples / tools in their curriculum. +In order for us to verify your eligibility for free usage, please [register for trial](https://Infragistics.com/Angular) and open a support ticket with a request for free license. + +To acquire a license for commercial usage, please [register for trial](https://Infragistics.com/Angular) and refer to the purchasing options in the pricing section on the product page. + +© Copyright 2020 INFRAGISTICS. All Rights Reserved. +The Infragistics Ultimate license & copyright applies to this distribution. +For information on that license, please go to our website [https://www.infragistics.com/legal/license](https://www.infragistics.com/legal/license). diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..be802c4 --- /dev/null +++ b/biome.json @@ -0,0 +1,62 @@ +{ + "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", + "files": { + "includes": ["**/src/**/*.ts", "**/src/**/*.js", "**/stories/**/*.ts"] + }, + "vcs": { + "clientKind": "git", + "useIgnoreFile": true + }, + "assist": { + "includes": ["**/src/**/*.ts", "!src/index.ts"], + "actions": { + "source": { + "organizeImports": "on" + } + } + }, + "formatter": { + "enabled": false + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "complexity": { + "noForEach": "off", + "noStaticOnlyClass": "off" + }, + "correctness": { + "noUnusedVariables": "error", + "noUnusedFunctionParameters": "error", + "noUnusedImports": "error", + "noUnusedPrivateClassMembers": "error", + "useImportExtensions": { + "level": "error", + "options": { "forceJsExtensions": true } + } + }, + "style": { + "noNamespace": "error", + "useCollapsedElseIf": "error", + "noNonNullAssertion": "off", + "noParameterAssign": "off", + "useAsConstAssertion": "error", + "useDefaultParameterLast": "error", + "useEnumInitializers": "error", + "useSelfClosingElements": "error", + "useSingleVarDeclarator": "error", + "noUnusedTemplateLiteral": "error", + "useNumberNamespace": "error", + "noInferrableTypes": "error", + "noUselessElse": "off", + "useTemplate": "off" + }, + "suspicious": { + "noConsole": "off", + "noDebugger": "error", + "noExplicitAny": "off" + } + } + } +} diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..12b9868 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,25 @@ +'use strict'; + +const gulp = require('gulp'); +const path = require('path'); +const del = require('del'); + +exports.cleanCoreBuild = () => { + return del.deleteAsync('dist/igniteui-i18n-core/**', { force: true }); +}; + +exports.cleanResourcesBuild = () => { + return del.deleteAsync('dist/igniteui-i18n-resources/**', { force: true }); +}; + +exports.copyPackageForCore = () => { + return gulp + .src([path.join(__dirname, 'projects/igniteui-i18n-core/package.json')]) + .pipe(gulp.dest(path.join(__dirname, 'dist/igniteui-i18n-core'))); +}; + +exports.copyPackageForResources = () => { + return gulp + .src([path.join(__dirname, 'projects/igniteui-i18n-resources/package.json')]) + .pipe(gulp.dest(path.join(__dirname, 'dist/igniteui-i18n-resources'))); +}; diff --git a/index.html b/index.html new file mode 100644 index 0000000..eb5b198 --- /dev/null +++ b/index.html @@ -0,0 +1,6 @@ + + + Ignite UI i18n Empty TestBed + + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..228e27b --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6943 @@ +{ + "name": "igniteui-i18n", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "igniteui-i18n", + "version": "0.0.0", + "devDependencies": { + "@biomejs/biome": "^2.2.4", + "@types/node": "^20.11.0", + "@vitest/browser": "^3.2.4", + "@vitest/coverage-istanbul": "^3.2.4", + "del": "^8.0.1", + "gulp": "^5.0.1", + "jsdom": "^26.1.0", + "playwright": "^1.54.1", + "prettier": "^3.6.2", + "typescript": "~5.8.3", + "typescript-eslint": "^8.38.0", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^3.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, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@asamuzakjp/css-color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", + "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.3", + "@csstools/css-color-parser": "^3.0.9", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + } + }, + "node_modules/@asamuzakjp/css-color/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, + "license": "ISC" + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", + "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", + "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.0", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.27.3", + "@babel/helpers": "^7.27.6", + "@babel/parser": "^7.28.0", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.0", + "@babel/types": "^7.28.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", + "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.0", + "@babel/types": "^7.28.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "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, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz", + "integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", + "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz", + "integrity": "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", + "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.0", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@biomejs/biome": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.2.4.tgz", + "integrity": "sha512-TBHU5bUy/Ok6m8c0y3pZiuO/BZoY/OcGxoLlrfQof5s8ISVwbVBdFINPQZyFfKwil8XibYWb7JMwnT8wT4WVPg==", + "dev": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "2.2.4", + "@biomejs/cli-darwin-x64": "2.2.4", + "@biomejs/cli-linux-arm64": "2.2.4", + "@biomejs/cli-linux-arm64-musl": "2.2.4", + "@biomejs/cli-linux-x64": "2.2.4", + "@biomejs/cli-linux-x64-musl": "2.2.4", + "@biomejs/cli-win32-arm64": "2.2.4", + "@biomejs/cli-win32-x64": "2.2.4" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.2.4.tgz", + "integrity": "sha512-RJe2uiyaloN4hne4d2+qVj3d3gFJFbmrr5PYtkkjei1O9c+BjGXgpUPVbi8Pl8syumhzJjFsSIYkcLt2VlVLMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.2.4.tgz", + "integrity": "sha512-cFsdB4ePanVWfTnPVaUX+yr8qV8ifxjBKMkZwN7gKb20qXPxd/PmwqUH8mY5wnM9+U0QwM76CxFyBRJhC9tQwg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.2.4.tgz", + "integrity": "sha512-M/Iz48p4NAzMXOuH+tsn5BvG/Jb07KOMTdSVwJpicmhN309BeEyRyQX+n1XDF0JVSlu28+hiTQ2L4rZPvu7nMw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.2.4.tgz", + "integrity": "sha512-7TNPkMQEWfjvJDaZRSkDCPT/2r5ESFPKx+TEev+I2BXDGIjfCZk2+b88FOhnJNHtksbOZv8ZWnxrA5gyTYhSsQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.2.4.tgz", + "integrity": "sha512-orr3nnf2Dpb2ssl6aihQtvcKtLySLta4E2UcXdp7+RTa7mfJjBgIsbS0B9GC8gVu0hjOu021aU8b3/I1tn+pVQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.2.4.tgz", + "integrity": "sha512-m41nFDS0ksXK2gwXL6W6yZTYPMH0LughqbsxInSKetoH6morVj43szqKx79Iudkp8WRT5SxSh7qVb8KCUiewGg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.2.4.tgz", + "integrity": "sha512-NXnfTeKHDFUWfxAefa57DiGmu9VyKi0cDqFpdI+1hJWQjGJhJutHPX0b5m+eXvTKOaf+brU+P0JrQAZMb5yYaQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.2.4.tgz", + "integrity": "sha512-3Y4V4zVRarVh/B/eSHczR4LYoSVyv3Dfuvm3cWs5w/HScccS0+Wt/lHOcDTRYeHjQmMYVC3rIRWqyN2EI52+zg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", + "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.10.tgz", + "integrity": "sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.0.2", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz", + "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz", + "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz", + "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz", + "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz", + "integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz", + "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz", + "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz", + "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz", + "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz", + "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz", + "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz", + "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz", + "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz", + "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz", + "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz", + "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz", + "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz", + "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz", + "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz", + "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz", + "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz", + "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz", + "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz", + "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz", + "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz", + "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/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, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz", + "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz", + "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz", + "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz", + "integrity": "sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@eslint/core": "^0.15.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@gulpjs/messages": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz", + "integrity": "sha512-Ys9sazDatyTgZVb4xPlDufLweJ/Os2uHWOv+Caxvy2O85JcnT4M3vc73bi8pdLWlv3fdWQz3pdI9tVwo8rQQSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@gulpjs/to-absolute-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@gulpjs/to-absolute-glob/-/to-absolute-glob-4.0.0.tgz", + "integrity": "sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-negated-glob": "^1.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "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, + "license": "ISC", + "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/@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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "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, + "license": "MIT", + "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, + "license": "MIT", + "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, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "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, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.2.tgz", + "integrity": "sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.2.tgz", + "integrity": "sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.2.tgz", + "integrity": "sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.2.tgz", + "integrity": "sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.2.tgz", + "integrity": "sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.2.tgz", + "integrity": "sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.2.tgz", + "integrity": "sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.2.tgz", + "integrity": "sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.2.tgz", + "integrity": "sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.2.tgz", + "integrity": "sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.2.tgz", + "integrity": "sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.2.tgz", + "integrity": "sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.2.tgz", + "integrity": "sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.2.tgz", + "integrity": "sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.2.tgz", + "integrity": "sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.2.tgz", + "integrity": "sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.2.tgz", + "integrity": "sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.2.tgz", + "integrity": "sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.2.tgz", + "integrity": "sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.2.tgz", + "integrity": "sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "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, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/user-event": { + "version": "14.6.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", + "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/chai": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", + "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT", + "peer": true + }, + "node_modules/@types/node": { + "version": "20.19.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.11.tgz", + "integrity": "sha512-uug3FEEGv0r+jrecvUUpbY8lLisvIjg6AAic6a2bSP5OEOLeJsDSnvhCDov7ipFFMXS3orMpzlmi0ZcuGkBbow==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.38.0.tgz", + "integrity": "sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.38.0", + "@typescript-eslint/type-utils": "8.38.0", + "@typescript-eslint/utils": "8.38.0", + "@typescript-eslint/visitor-keys": "8.38.0", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.38.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.38.0.tgz", + "integrity": "sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.38.0", + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/typescript-estree": "8.38.0", + "@typescript-eslint/visitor-keys": "8.38.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.38.0.tgz", + "integrity": "sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.38.0", + "@typescript-eslint/types": "^8.38.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.38.0.tgz", + "integrity": "sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/visitor-keys": "8.38.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz", + "integrity": "sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.38.0.tgz", + "integrity": "sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/typescript-estree": "8.38.0", + "@typescript-eslint/utils": "8.38.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.38.0.tgz", + "integrity": "sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz", + "integrity": "sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.38.0", + "@typescript-eslint/tsconfig-utils": "8.38.0", + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/visitor-keys": "8.38.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "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, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.38.0.tgz", + "integrity": "sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.38.0", + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/typescript-estree": "8.38.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz", + "integrity": "sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.38.0", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitest/browser": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-3.2.4.tgz", + "integrity": "sha512-tJxiPrWmzH8a+w9nLKlQMzAKX/7VjFs50MWgcAj7p9XQ7AQ9/35fByFYptgPELyLw+0aixTnC4pUWV+APcZ/kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@testing-library/dom": "^10.4.0", + "@testing-library/user-event": "^14.6.1", + "@vitest/mocker": "3.2.4", + "@vitest/utils": "3.2.4", + "magic-string": "^0.30.17", + "sirv": "^3.0.1", + "tinyrainbow": "^2.0.0", + "ws": "^8.18.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "playwright": "*", + "vitest": "3.2.4", + "webdriverio": "^7.0.0 || ^8.0.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": true + }, + "safaridriver": { + "optional": true + }, + "webdriverio": { + "optional": true + } + } + }, + "node_modules/@vitest/coverage-istanbul": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/coverage-istanbul/-/coverage-istanbul-3.2.4.tgz", + "integrity": "sha512-IDlpuFJiWU9rhcKLkpzj8mFu/lpe64gVgnV15ZOrYx1iFzxxrxCzbExiUEKtwwXRvEiEMUS6iZeYgnMxgbqbxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@istanbuljs/schema": "^0.1.3", + "debug": "^4.4.1", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-instrument": "^6.0.3", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.1.7", + "magicast": "^0.3.5", + "test-exclude": "^7.0.1", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "3.2.4" + } + }, + "node_modules/@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.2.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.2.4", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peer": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "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, + "license": "MIT", + "peer": 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/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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "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, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "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, + "license": "Python-2.0", + "peer": true + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/async-done": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/async-done/-/async-done-2.0.0.tgz", + "integrity": "sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.4.4", + "once": "^1.4.0", + "stream-exhaust": "^1.0.2" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/async-settle": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-2.0.0.tgz", + "integrity": "sha512-Obu/KE8FurfQRN6ODdHN9LuXqwC+JFIM9NRyZqJJ4ZfLJmIYN9Rg0/kb+wF70VV5+fJusTMQlJ1t5rF7J/ETdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-done": "^2.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/b4a": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/bach": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bach/-/bach-2.0.1.tgz", + "integrity": "sha512-A7bvGMGiTOxGMpNupYl9HQTf0FFDNF4VCmks4PJpFyN1AX2pdKuxuwdvUz2Hu388wcgp+OvGFNsumBfFNkR7eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-done": "^2.0.0", + "async-settle": "^2.0.0", + "now-and-later": "^3.0.0" + }, + "engines": { + "node": ">=10.13.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, + "license": "MIT" + }, + "node_modules/bare-events": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.6.0.tgz", + "integrity": "sha512-EKZ5BTXYExaNqi3I3f9RtEsaI/xBSGjE0XZCZilPzFAV/goswFHuPd9jEZlPIZ/iNZJwDSao9qRiScySz7MbQg==", + "dev": true, + "license": "Apache-2.0", + "optional": 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" + } + ], + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "peer": 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, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", + "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" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "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.2.1" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001731", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz", + "integrity": "sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==", + "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" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chai": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.1.tgz", + "integrity": "sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "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, + "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/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "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, + "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/chokidar/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, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "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, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/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, + "license": "MIT" + }, + "node_modules/cliui/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, + "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/cliui/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, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "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": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "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, + "license": "MIT", + "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, + "license": "MIT" + }, + "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, + "license": "MIT", + "peer": true + }, + "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, + "license": "MIT" + }, + "node_modules/copy-props": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-4.0.0.tgz", + "integrity": "sha512-bVWtw1wQLzzKiYROtvNlbJgxgBYt2bMJpkCbKmXM3xyijvcjjWXEk5nyrrT3bgJ7ODb19ZohE2T0Y3FgNPyoTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "each-props": "^3.0.0", + "is-plain-object": "^5.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssstyle": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", + "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^3.2.0", + "rrweb-cssom": "^0.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/del": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/del/-/del-8.0.1.tgz", + "integrity": "sha512-gPqh0mKTPvaUZGAuHbrBUYKZWBNAeHG7TU3QH5EhVwPMyKvmfJaNXhcD2jTcXsJRRcffuho4vaYweu80dRrMGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "globby": "^14.0.2", + "is-glob": "^4.0.3", + "is-path-cwd": "^3.0.0", + "is-path-inside": "^4.0.0", + "p-map": "^7.0.2", + "presentable-error": "^0.0.1", + "slash": "^5.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/each-props": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/each-props/-/each-props-3.0.0.tgz", + "integrity": "sha512-IYf1hpuWrdzse/s/YJOrFmU15lyhSzxelNVAHTEG3DtP4QsLTWZUzcUL3HMXmKQxXpa4EIrBPpwRgj0aehdvAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^5.0.0", + "object.defaults": "^1.1.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "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, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.193", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.193.tgz", + "integrity": "sha512-eePuBZXM9OVCwfYUhd2OzESeNGnWmLyeu0XAEjf7xjijNjHFdeJSzuRUGN4ueT2tEYo5YqjHramKEFxz67p3XA==", + "dev": true, + "license": "ISC" + }, + "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, + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", + "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.8", + "@esbuild/android-arm": "0.25.8", + "@esbuild/android-arm64": "0.25.8", + "@esbuild/android-x64": "0.25.8", + "@esbuild/darwin-arm64": "0.25.8", + "@esbuild/darwin-x64": "0.25.8", + "@esbuild/freebsd-arm64": "0.25.8", + "@esbuild/freebsd-x64": "0.25.8", + "@esbuild/linux-arm": "0.25.8", + "@esbuild/linux-arm64": "0.25.8", + "@esbuild/linux-ia32": "0.25.8", + "@esbuild/linux-loong64": "0.25.8", + "@esbuild/linux-mips64el": "0.25.8", + "@esbuild/linux-ppc64": "0.25.8", + "@esbuild/linux-riscv64": "0.25.8", + "@esbuild/linux-s390x": "0.25.8", + "@esbuild/linux-x64": "0.25.8", + "@esbuild/netbsd-arm64": "0.25.8", + "@esbuild/netbsd-x64": "0.25.8", + "@esbuild/openbsd-arm64": "0.25.8", + "@esbuild/openbsd-x64": "0.25.8", + "@esbuild/openharmony-arm64": "0.25.8", + "@esbuild/sunos-x64": "0.25.8", + "@esbuild/win32-arm64": "0.25.8", + "@esbuild/win32-ia32": "0.25.8", + "@esbuild/win32-x64": "0.25.8" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.32.0.tgz", + "integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.3.0", + "@eslint/core": "^0.15.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.32.0", + "@eslint/plugin-kit": "^0.3.4", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "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, + "license": "BSD-2-Clause", + "peer": 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, + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.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, + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect-type": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", + "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "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, + "license": "MIT" + }, + "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, + "license": "MIT", + "peer": true + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "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.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/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, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "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, + "license": "MIT", + "peer": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/findup-sync": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz", + "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.3", + "micromatch": "^4.0.4", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/fined": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-2.0.0.tgz", + "integrity": "sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A==", + "dev": true, + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^5.0.0", + "object.defaults": "^1.1.0", + "object.pick": "^1.3.0", + "parse-filepath": "^1.0.2" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/flagged-respawn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-2.0.0.tgz", + "integrity": "sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", + "dev": true, + "license": "MIT", + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fs-mkdirp-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz", + "integrity": "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.8", + "streamx": "^2.12.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": 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", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "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, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "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, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "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, + "license": "ISC", + "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/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, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-stream": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.3.tgz", + "integrity": "sha512-fqZVj22LtFJkHODT+M4N1RJQ3TjnnQhfE9GwZI8qXscYarnhpip70poMldRnP8ipQ/w0B621kOhfc53/J9bd/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@gulpjs/to-absolute-glob": "^4.0.0", + "anymatch": "^3.1.3", + "fastq": "^1.13.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "is-negated-glob": "^1.0.0", + "normalize-path": "^3.0.0", + "streamx": "^2.12.5" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-watcher": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-6.0.0.tgz", + "integrity": "sha512-wGM28Ehmcnk2NqRORXFOTOR064L4imSw3EeOqU5bIwUf62eXGwg89WivH6VMahL8zlQHeodzvHpXplrqzrz3Nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-done": "^2.0.0", + "chokidar": "^3.5.3" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/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, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/glogg": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-2.2.0.tgz", + "integrity": "sha512-eWv1ds/zAlz+M1ioHsyKJomfY7jbDDPpwSkv14KQj89bycx1nvK5/2Cj/T9g7kzJcX5Bc7Yv22FjfBZS/jl94A==", + "dev": true, + "license": "MIT", + "dependencies": { + "sparkles": "^2.1.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "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, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/gulp": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-5.0.1.tgz", + "integrity": "sha512-PErok3DZSA5WGMd6XXV3IRNO0mlB+wW3OzhFJLEec1jSERg2j1bxJ6e5Fh6N6fn3FH2T9AP4UYNb/pYlADB9sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-watcher": "^6.0.0", + "gulp-cli": "^3.1.0", + "undertaker": "^2.0.0", + "vinyl-fs": "^4.0.2" + }, + "bin": { + "gulp": "bin/gulp.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gulp-cli": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.1.0.tgz", + "integrity": "sha512-zZzwlmEsTfXcxRKiCHsdyjZZnFvXWM4v1NqBJSYbuApkvVKivjcmOS2qruAJ+PkEHLFavcDKH40DPc1+t12a9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@gulpjs/messages": "^1.1.0", + "chalk": "^4.1.2", + "copy-props": "^4.0.0", + "gulplog": "^2.2.0", + "interpret": "^3.1.1", + "liftoff": "^5.0.1", + "mute-stdout": "^2.0.0", + "replace-homedir": "^2.0.0", + "semver-greatest-satisfied-range": "^2.0.0", + "string-width": "^4.2.3", + "v8flags": "^4.0.0", + "yargs": "^16.2.0" + }, + "bin": { + "gulp": "bin/gulp.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gulp-cli/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, + "license": "MIT" + }, + "node_modules/gulp-cli/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, + "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/gulp-cli/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, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gulplog": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-2.2.0.tgz", + "integrity": "sha512-V2FaKiOhpR3DRXZuYdRLn/qiY0yI5XmqbTKrYbdemJ+xOh2d2MOweI/XFgMzd/9+1twdvMwllnZbWZNJ+BOm4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "glogg": "^2.2.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "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, + "license": "MIT" + }, + "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, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "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, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.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" + } + ], + "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, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.19" + } + }, + "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, + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "license": "MIT", + "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, + "license": "MIT", + "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, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-3.0.0.tgz", + "integrity": "sha512-kyiNFFLU0Ampr6SDZitD/DwUo4Zs1nSdnygUBqsu3LooL00Qvb5j+UnvApUn/TTj1J3OuE6BTdQ5rudKmU2ZaA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "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, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unc-path": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "unc-path-regex": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "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, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "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, + "license": "BSD-3-Clause", + "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/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, + "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-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "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, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "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, + "license": "MIT" + }, + "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, + "license": "MIT", + "peer": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", + "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssstyle": "^4.2.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.5.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.16", + "parse5": "^7.2.1", + "rrweb-cssom": "^0.8.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.1.1", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.1.1", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": 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, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "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, + "license": "MIT", + "peer": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT", + "peer": 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, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/last-run": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/last-run/-/last-run-2.0.0.tgz", + "integrity": "sha512-j+y6WhTLN4Itnf9j5ZQos1BGPCS8DAwmgMroR3OzfxAsBxam0hMw7J8M3KqZl0pLQJ1jNnwIexg5DYpC/ctwEQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/lead": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-4.0.0.tgz", + "integrity": "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/liftoff": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.1.tgz", + "integrity": "sha512-wwLXMbuxSF8gMvubFcFRp56lkFV69twvbU5vDPbaw+Q+/rF8j0HKjGbIdlSi+LuJm9jf7k9PB+nTxnsLMPcv2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend": "^3.0.2", + "findup-sync": "^5.0.0", + "fined": "^2.0.0", + "flagged-respawn": "^2.0.0", + "is-plain-object": "^5.0.0", + "rechoir": "^0.8.0", + "resolve": "^1.20.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "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, + "license": "MIT", + "peer": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/loupe": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.0.tgz", + "integrity": "sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/magicast": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.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, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "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, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "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, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "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, + "license": "MIT" + }, + "node_modules/mute-stdout": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-2.0.0.tgz", + "integrity": "sha512-32GSKM3Wyc8dg/p39lWPKYu8zci9mJFzV1Np9Of0ZEpe6Fhssn/FbI7ywAMd40uX+p3ZKh3T5EeCFv81qS3HmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "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/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT" + }, + "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, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/now-and-later": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz", + "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/nwsapi": { + "version": "2.2.21", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.21.tgz", + "integrity": "sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "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, + "license": "MIT", + "peer": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "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, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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, + "license": "BlueOak-1.0.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, + "license": "MIT", + "peer": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "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, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "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, + "license": "MIT", + "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, + "license": "MIT" + }, + "node_modules/path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-root-regex": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "license": "BlueOak-1.0.0", + "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, + "license": "ISC" + }, + "node_modules/path-type": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "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, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/playwright": { + "version": "1.54.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.54.1.tgz", + "integrity": "sha512-peWpSwIBmSLi6aW2auvrUtf2DqY16YYcCMO8rTVx486jKmDTJg7UAhyrraP98GB8BoPURZP8+nxO7TSd4cPr5g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.54.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.54.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.54.1.tgz", + "integrity": "sha512-Nbjs2zjj0htNhzgiy5wu+3w09YetDx5pkrpI/kZotDlDUaYk0HVA5xrBVPdow4SAUIlhgKcJeJg4GRKW6xHusA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "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" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/presentable-error": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/presentable-error/-/presentable-error-0.0.1.tgz", + "integrity": "sha512-E6rsNU1QNJgB3sjj7OANinGncFKuK+164sLXw1/CqBjj/EkXSoSdHCtWQGBNlREIGLnL7IEUEGa08YFVUbrhVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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" + } + ], + "license": "MIT" + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT" + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true, + "license": "ISC" + }, + "node_modules/replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/replace-homedir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-2.0.0.tgz", + "integrity": "sha512-bgEuQQ/BHW0XkkJtawzrfzHFSN70f/3cNOiHa2QsYxqrjaC30X1k74FJ6xswVBP0sr0SpGIdVFuPwfrYziVeyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.13.0" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-options": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-2.0.0.tgz", + "integrity": "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "value-or-function": "^4.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz", + "integrity": "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.46.2", + "@rollup/rollup-android-arm64": "4.46.2", + "@rollup/rollup-darwin-arm64": "4.46.2", + "@rollup/rollup-darwin-x64": "4.46.2", + "@rollup/rollup-freebsd-arm64": "4.46.2", + "@rollup/rollup-freebsd-x64": "4.46.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.46.2", + "@rollup/rollup-linux-arm-musleabihf": "4.46.2", + "@rollup/rollup-linux-arm64-gnu": "4.46.2", + "@rollup/rollup-linux-arm64-musl": "4.46.2", + "@rollup/rollup-linux-loongarch64-gnu": "4.46.2", + "@rollup/rollup-linux-ppc64-gnu": "4.46.2", + "@rollup/rollup-linux-riscv64-gnu": "4.46.2", + "@rollup/rollup-linux-riscv64-musl": "4.46.2", + "@rollup/rollup-linux-s390x-gnu": "4.46.2", + "@rollup/rollup-linux-x64-gnu": "4.46.2", + "@rollup/rollup-linux-x64-musl": "4.46.2", + "@rollup/rollup-win32-arm64-msvc": "4.46.2", + "@rollup/rollup-win32-ia32-msvc": "4.46.2", + "@rollup/rollup-win32-x64-msvc": "4.46.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "dev": true, + "license": "MIT" + }, + "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" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-greatest-satisfied-range": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-2.0.0.tgz", + "integrity": "sha512-lH3f6kMbwyANB7HuOWRMlLCa2itaCrZJ+SAqqkSZrZKO/cAsk2EOyaKHUtNkVLFyFW9pct22SFesFp3Z7zpA0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "sver": "^1.8.3" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "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, + "license": "MIT", + "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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "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, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sirv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.1.tgz", + "integrity": "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sparkles": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-2.1.0.tgz", + "integrity": "sha512-r7iW1bDw8R/cFifrD3JnQJX0K1jqT0kprL48BiBpLZLJPmAm34zsVBsK5lc7HirZYZqMW65dOXZgbAGt/I6frg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", + "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", + "dev": true, + "license": "MIT" + }, + "node_modules/stream-composer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz", + "integrity": "sha512-bnBselmwfX5K10AH6L4c8+S5lgZMWI7ZYrz2rvYjCPB2DIMC4Ig8OpxGpNJSxRZ58oti7y1IcNvjBAz9vW5m4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "streamx": "^2.13.2" + } + }, + "node_modules/stream-exhaust": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", + "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", + "dev": true, + "license": "MIT" + }, + "node_modules/streamx": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.1.tgz", + "integrity": "sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-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, + "license": "MIT", + "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/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, + "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/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, + "license": "MIT" + }, + "node_modules/string-width-cjs/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, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "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, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi/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, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", + "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sver": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/sver/-/sver-1.8.4.tgz", + "integrity": "sha512-71o1zfzyawLfIWBOmw8brleKyvnbn73oVHNCsu51uPMz/HWiKkkXsI31JjHW5zqXEqnPYkIiHd8ZmL7FCimLEA==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "semver": "^6.3.0" + } + }, + "node_modules/sver/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, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/teex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", + "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "streamx": "^2.12.5" + } + }, + "node_modules/test-exclude": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", + "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^9.0.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/test-exclude/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, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz", + "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", + "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.86" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", + "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-through": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-3.0.0.tgz", + "integrity": "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "streamx": "^2.12.5" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^6.1.32" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tsconfck": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", + "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", + "dev": true, + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.38.0.tgz", + "integrity": "sha512-FsZlrYK6bPDGoLeZRuvx2v6qrM03I0U0SnfCLPs/XCCPCFD80xU9Pg09H/K+XFa68uJuZo7l/Xhs+eDRg2l3hg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.38.0", + "@typescript-eslint/parser": "8.38.0", + "@typescript-eslint/typescript-estree": "8.38.0", + "@typescript-eslint/utils": "8.38.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/undertaker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-2.0.0.tgz", + "integrity": "sha512-tO/bf30wBbTsJ7go80j0RzA2rcwX6o7XPBpeFcb+jzoeb4pfMM2zUeSDIkY1AWqeZabWxaQZ/h8N9t35QKDLPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bach": "^2.0.1", + "fast-levenshtein": "^3.0.0", + "last-run": "^2.0.0", + "undertaker-registry": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/undertaker-registry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-2.0.0.tgz", + "integrity": "sha512-+hhVICbnp+rlzZMgxXenpvTxpuvA67Bfgtt+O9WOE5jo7w/dyiF1VmoZVIHvP2EkUjsyKyTwYKlLhA+j47m1Ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/undertaker/node_modules/fast-levenshtein": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", + "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fastest-levenshtein": "^1.0.7" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "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" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "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, + "license": "BSD-2-Clause", + "peer": 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, + "license": "MIT" + }, + "node_modules/v8flags": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz", + "integrity": "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/value-or-function": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz", + "integrity": "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/vinyl": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.1.tgz", + "integrity": "sha512-0QwqXteBNXgnLCdWdvPQBX6FXRHtIH3VhJPTd5Lwn28tJXc34YqSCWUmkOvtJHBmB3gGoPtrOKk3Ts8/kEZ9aA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^2.1.2", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-contents": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz", + "integrity": "sha512-cHq6NnGyi2pZ7xwdHSW1v4Jfnho4TEGtxZHw01cmnc8+i7jgR6bRnED/LbrKan/Q7CvVLbnvA5OepnhbpjBZ5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^5.0.0", + "vinyl": "^3.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-fs": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.2.tgz", + "integrity": "sha512-XRFwBLLTl8lRAOYiBqxY279wY46tVxLaRhSwo3GzKEuLz1giffsOquWWboD/haGf5lx+JyTigCFfe7DWHoARIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fs-mkdirp-stream": "^2.0.1", + "glob-stream": "^8.0.3", + "graceful-fs": "^4.2.11", + "iconv-lite": "^0.6.3", + "is-valid-glob": "^1.0.0", + "lead": "^4.0.0", + "normalize-path": "3.0.0", + "resolve-options": "^2.0.0", + "stream-composer": "^1.0.2", + "streamx": "^2.14.0", + "to-through": "^3.0.0", + "value-or-function": "^4.0.0", + "vinyl": "^3.0.1", + "vinyl-sourcemap": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-sourcemap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-2.0.0.tgz", + "integrity": "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "convert-source-map": "^2.0.0", + "graceful-fs": "^4.2.10", + "now-and-later": "^3.0.0", + "streamx": "^2.12.5", + "vinyl": "^3.0.0", + "vinyl-contents": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vite": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.6.tgz", + "integrity": "sha512-MHFiOENNBd+Bd9uvc8GEsIzdkn1JxMmEeYX35tI3fv0sJBUTfW5tQsoaOwuY4KhBI09A3dUJ/DXf2yxPVPUceg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.6", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.40.0", + "tinyglobby": "^0.2.14" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-tsconfig-paths": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-5.1.4.tgz", + "integrity": "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "tsconfck": "^3.0.3" + }, + "peerDependencies": { + "vite": "*" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/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, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vitest": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.2.4", + "@vitest/ui": "3.2.4", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "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, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-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, + "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/wrap-ansi-cjs/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, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/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, + "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/wrap-ansi-cjs/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, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "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, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "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/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, + "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, + "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, + "license": "ISC" + }, + "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, + "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/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, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/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, + "license": "MIT" + }, + "node_modules/yargs/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, + "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/yargs/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, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..6c76788 --- /dev/null +++ b/package.json @@ -0,0 +1,32 @@ +{ + "name": "igniteui-i18n", + "version": "0.0.0", + "scripts": { + "build": "npm run build:core && npm run build:resources", + "build:core": "gulp cleanCoreBuild && tsc --project projects/igniteui-i18n-core/tsconfig.build.json && gulp copyPackageForCore", + "build:resources": "gulp cleanResourcesBuild && tsc --project projects/igniteui-i18n-resources/tsconfig.build.json && gulp copyPackageForResources", + "lint": "npm run lint:biome && npm run lint:prettier", + "lint:fix": "npm run lint:biome:fix && npm run lint:prettier:fix", + "lint:biome": "biome lint", + "lint:biome:fix": "biome check --write", + "lint:prettier": "prettier . --check", + "lint:prettier:fix": "prettier . --write", + "test": "vitest --config vitest.browser.config.ts", + "test:inline": "vitest" + }, + "devDependencies": { + "@biomejs/biome": "^2.2.4", + "@types/node": "^20.11.0", + "@vitest/browser": "^3.2.4", + "@vitest/coverage-istanbul": "^3.2.4", + "del": "^8.0.1", + "gulp": "^5.0.1", + "jsdom": "^26.1.0", + "playwright": "^1.54.1", + "prettier": "^3.6.2", + "typescript": "~5.8.3", + "typescript-eslint": "^8.38.0", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^3.2.4" + } +} diff --git a/projects/igniteui-i18n-core/package.json b/projects/igniteui-i18n-core/package.json new file mode 100644 index 0000000..28ad4ca --- /dev/null +++ b/projects/igniteui-i18n-core/package.json @@ -0,0 +1,38 @@ +{ + "name": "igniteui-i18n-core", + "version": "1.0.0", + "description": "IgniteUI for Angular localization resources package", + "author": "Infragistics", + "license": "SEE LICENSE IN LICENSE", + "homepage": "https://github.com/IgniteUI/igniteui-angular/projects/igniteui-i18n-core", + "repository": { + "type": "git", + "url": "https://github.com/IgniteUI/igniteui-i18n.git", + "directory": "projects/igniteui-i18n-core" + }, + "bugs": { + "url": "https://github.com/IgniteUI/igniteui-angular/issues" + }, + "keywords": [ + "IgniteUI", + "Angular", + "i18n", + "Infragistics" + ], + "type": "module", + "main": "./index.js", + "types": "./index.d.ts", + "exports": { + ".": "./index.js", + "./en": "./i18n/EN/index.js" + }, + "sideEffects": false, + "peerDependencies": { + "igniteui-i18n-resources": "^1.0.0" + }, + "peerDependenciesMeta": { + "igniteui-i18n-resources": { + "optional": true + } + } +} diff --git a/projects/igniteui-i18n-core/src/formatters/base.formatter.ts b/projects/igniteui-i18n-core/src/formatters/base.formatter.ts new file mode 100644 index 0000000..d4b2b7c --- /dev/null +++ b/projects/igniteui-i18n-core/src/formatters/base.formatter.ts @@ -0,0 +1,37 @@ +import type { I18nFormatter, I18nFormatterOptions, IntlFormatter } from '../i18n-manager.interfaces.js'; +import { generateLocaleKey, mergeOptions } from '../utils.js'; + +export class BaseFormatter { + public defaultOptions = {} as O; + protected cachedIntlFormatters = new Map(); + protected currentLocale: string; + protected formatterType: IntlFormatter; + + constructor(defaultLocale: string, formatterType: IntlFormatter) { + this.currentLocale = defaultLocale; + this.formatterType = formatterType; + } + + /** Method that should be called once the global locale changes. Prevents parent reference to i18n manager. */ + public onLocaleChange(newLocale: string) { + this.currentLocale = newLocale; + } + + /** + * Get inner Intl formatter from cache, otherwise create it and cache it for further use. Time to retrieve cached formatter: ~0-0.1ms + * @param locale Locale for which to get a specific formatter + * @param options Options the formatter needs to have set + * @returns The formatter desired + */ + public getIntlFormatter(locale?: string, options?: O) { + const combinedOptions = mergeOptions(this.defaultOptions, options); + const canonLocale = locale ? Intl.getCanonicalLocales(locale)[0] : this.currentLocale; + const formatterKey = generateLocaleKey(canonLocale, combinedOptions); + let formatter = this.cachedIntlFormatters.get(formatterKey); + if (!formatter) { + formatter = new this.formatterType(canonLocale, combinedOptions); + this.cachedIntlFormatters.set(formatterKey, formatter); + } + return formatter; + } +} diff --git a/projects/igniteui-i18n-core/src/formatters/date.formatter.spec.ts b/projects/igniteui-i18n-core/src/formatters/date.formatter.spec.ts new file mode 100644 index 0000000..af2a995 --- /dev/null +++ b/projects/igniteui-i18n-core/src/formatters/date.formatter.spec.ts @@ -0,0 +1,755 @@ +import { describe, expect, it } from 'vitest'; +import { DateFormatter } from './date.formatter.js'; +import { LocaleFormatter } from './locale.formatter.js'; + +describe('i18n tests', () => { + const basicDate = new Date('12/3/2014'); + const dateTime = new Date('2014-12-03T03:24:00'); + const dateTime2 = new Date('2014-03-21T06:24:13'); + const dateTimeHourFull = new Date('2014-03-21T16:08:09'); + const localeFormatter = new LocaleFormatter('en'); + const dateFormatter = new DateFormatter('en', localeFormatter); + + describe('date formatting', () => { + it('should get correct first date of the week per locale', () => { + // Note: Using jsdom this will not pass + expect(dateFormatter.getFirstDayOfWeek('en')).equal(7); + expect(dateFormatter.getFirstDayOfWeek('bg')).equal(1); + expect(dateFormatter.getFirstDayOfWeek('ja')).equal(7); + expect(dateFormatter.getFirstDayOfWeek('es')).equal(1); + expect(dateFormatter.getFirstDayOfWeek('ar')).equal(6); + }); + + it('should format basic date with default options', () => { + expect(dateFormatter.formatDateTime(basicDate, 'en')).equal('12/3/2014'); + expect(dateFormatter.formatDateTime(basicDate, 'bg')).equal('3.12.2014 г.'); + expect(dateFormatter.formatDateTime(basicDate, 'ja')).equal('2014/12/3'); + expect(dateFormatter.formatDateTime(basicDate, 'es')).equal('3/12/2014'); + expect(dateFormatter.formatDateTime(basicDate, 'ar')).equal('3‏/12‏/2014'); // Note: Using jsdom this will not pass + + expect(dateFormatter.formatDateTime(dateTime, 'en')).equal('12/3/2014'); + expect(dateFormatter.formatDateTime(dateTime, 'bg')).equal('3.12.2014 г.'); + expect(dateFormatter.formatDateTime(dateTime, 'ja')).equal('2014/12/3'); + expect(dateFormatter.formatDateTime(dateTime, 'es')).equal('3/12/2014'); + expect(dateFormatter.formatDateTime(dateTime, 'ar')).equal('3‏/12‏/2014'); // Note: Using jsdom this will not pass + }); + + it('should format basic date time to long date per locale', () => { + const options: Intl.DateTimeFormatOptions = { + dateStyle: 'long' + }; + expect(dateFormatter.formatDateTime(dateTime, 'en', options)).equal('December 3, 2014'); + expect(dateFormatter.formatDateTime(dateTime, 'bg', options)).equal('3 декември 2014 г.'); + expect(dateFormatter.formatDateTime(dateTime, 'ja', options)).equal('2014年12月3日'); + expect(dateFormatter.formatDateTime(dateTime, 'es', options)).equal('3 de diciembre de 2014'); + expect(dateFormatter.formatDateTime(dateTime, 'ar', options)).equal('3 ديسمبر 2014'); + }); + + it('should format basic date time to short date time', () => { + const options: Intl.DateTimeFormatOptions = { + timeStyle: 'short', + dateStyle: 'short' + }; + expect(dateFormatter.formatDateTime(dateTime, 'en', options)).equal('12/3/14, 3:24 AM'); + expect(dateFormatter.formatDateTime(dateTime, 'bg', options)).equal('3.12.14 г., 3:24'); + expect(dateFormatter.formatDateTime(dateTime, 'ja', options)).equal('2014/12/03 3:24'); + expect(dateFormatter.formatDateTime(dateTime, 'es', options)).equal('3/12/14, 3:24'); + expect(dateFormatter.formatDateTime(dateTime, 'ar', options)).equal('3‏/12‏/2014 3:24 ص'); + }); + + it('should format basic date to short date time parts', () => { + const options: Intl.DateTimeFormatOptions = { + dateStyle: 'long' + }; + expect(dateFormatter.formatDateTimeToParts(dateTime, 'en', options)).toMatchObject([ + { type: 'month', value: 'December' }, + { type: 'literal', value: ' ' }, + { type: 'day', value: '3' }, + { type: 'literal', value: ', ' }, + { type: 'year', value: '2014' } + ]); + expect(dateFormatter.formatDateTimeToParts(dateTime, 'bg', options)).toMatchObject([ + { type: 'day', value: '3' }, + { type: 'literal', value: ' ' }, + { type: 'month', value: 'декември' }, + { type: 'literal', value: ' ' }, + { type: 'year', value: '2014' }, + { type: 'literal', value: ' г.' } + ]); + expect(dateFormatter.formatDateTimeToParts(dateTime, 'ja', options)).toMatchObject([ + { type: 'year', value: '2014' }, + { type: 'literal', value: '年' }, + { type: 'month', value: '12' }, + { type: 'literal', value: '月' }, + { type: 'day', value: '3' }, + { type: 'literal', value: '日' } + ]); + expect(dateFormatter.formatDateTimeToParts(dateTime, 'es', options)).toMatchObject([ + { type: 'day', value: '3' }, + { type: 'literal', value: ' de ' }, + { type: 'month', value: 'diciembre' }, + { type: 'literal', value: ' de ' }, + { type: 'year', value: '2014' } + ]); + expect(dateFormatter.formatDateTimeToParts(dateTime, 'ar', options)).toMatchObject([ + { type: 'day', value: '3' }, + { type: 'literal', value: ' ' }, + { type: 'month', value: 'ديسمبر' }, + { type: 'literal', value: ' ' }, + { type: 'year', value: '2014' } + ]); + }); + + it('should get correct default date formatting for different locales', () => { + expect(dateFormatter.getLocaleDateTimeFormat('en-US')).equal('M/d/yyyy'); + expect(dateFormatter.getLocaleDateTimeFormat('en-GB')).equal('dd/MM/yyyy'); + expect(dateFormatter.getLocaleDateTimeFormat('de')).equal('d.M.yyyy'); + expect(dateFormatter.getLocaleDateTimeFormat('ja')).equal('yyyy/M/d'); + expect(dateFormatter.getLocaleDateTimeFormat('es')).equal('d/M/yyyy'); + expect(dateFormatter.getLocaleDateTimeFormat('ar')).equal('d‏/M‏/yyyy'); + }); + + it('should get correct default date formatting for different locales with forced leading zero', () => { + expect(dateFormatter.getLocaleDateTimeFormat('en-US', true)).equal('MM/dd/yyyy'); + expect(dateFormatter.getLocaleDateTimeFormat('en-GB', true)).equal('dd/MM/yyyy'); + expect(dateFormatter.getLocaleDateTimeFormat('de', true)).equal('dd.MM.yyyy'); + expect(dateFormatter.getLocaleDateTimeFormat('ja', true)).equal('yyyy/MM/dd'); + expect(dateFormatter.getLocaleDateTimeFormat('es', true)).equal('dd/MM/yyyy'); + expect(dateFormatter.getLocaleDateTimeFormat('ar', true)).equal('dd‏/MM‏/yyyy'); + }); + + it('should get correct date formatting for different locales', () => { + expect(dateFormatter.getLocaleDateTimeFormat('en-US', false, { dateStyle: 'short' })).equal('M/d/yy'); + expect(dateFormatter.getLocaleDateTimeFormat('en-GB', false, { dateStyle: 'short' })).equal('dd/MM/yyyy'); + expect(dateFormatter.getLocaleDateTimeFormat('de', false, { dateStyle: 'short' })).equal('dd.MM.yy'); + expect(dateFormatter.getLocaleDateTimeFormat('ja', false, { dateStyle: 'short' })).equal('yyyy/MM/dd'); + expect(dateFormatter.getLocaleDateTimeFormat('es', false, { dateStyle: 'short' })).equal('d/M/yy'); + expect(dateFormatter.getLocaleDateTimeFormat('ar', false, { dateStyle: 'short' })).equal('d‏/M‏/yyyy'); + + expect(dateFormatter.getLocaleDateTimeFormat('en-US', false, { dateStyle: 'medium' })).equal('MMM d, yyyy'); + expect(dateFormatter.getLocaleDateTimeFormat('en-GB', false, { dateStyle: 'medium' })).equal('d MMM yyyy'); + expect(dateFormatter.getLocaleDateTimeFormat('de', false, { dateStyle: 'medium' })).equal('dd.MM.yyyy'); + expect(dateFormatter.getLocaleDateTimeFormat('ja', false, { dateStyle: 'medium' })).equal('yyyy/MM/dd'); + expect(dateFormatter.getLocaleDateTimeFormat('es', false, { dateStyle: 'medium' })).equal('d MMM yyyy'); + expect(dateFormatter.getLocaleDateTimeFormat('ar', false, { dateStyle: 'medium' })).equal('dd‏/MM‏/yyyy'); + + expect(dateFormatter.getLocaleDateTimeFormat('en-US', false, { dateStyle: 'long' })).equal('MMMM d, yyyy'); + expect(dateFormatter.getLocaleDateTimeFormat('en-GB', false, { dateStyle: 'long' })).equal('d MMMM yyyy'); + expect(dateFormatter.getLocaleDateTimeFormat('de', false, { dateStyle: 'long' })).equal('d. MMMM yyyy'); + expect(dateFormatter.getLocaleDateTimeFormat('ja', false, { dateStyle: 'long' })).equal('yyyy年M月d日'); + expect(dateFormatter.getLocaleDateTimeFormat('es', false, { dateStyle: 'long' })).equal( + 'd de MMMM de yyyy' + ); + expect(dateFormatter.getLocaleDateTimeFormat('ar', false, { dateStyle: 'long' })).equal('d MMMM yyyy'); + + expect(dateFormatter.getLocaleDateTimeFormat('en-US', false, { dateStyle: 'full' })).equal( + 'EEEE, MMMM d, yyyy' + ); + expect(dateFormatter.getLocaleDateTimeFormat('en-GB', false, { dateStyle: 'full' })).equal( + 'EEEE d MMMM yyyy' + ); + expect(dateFormatter.getLocaleDateTimeFormat('de', false, { dateStyle: 'full' })).equal( + 'EEEE, d. MMMM yyyy' + ); + expect(dateFormatter.getLocaleDateTimeFormat('ja', false, { dateStyle: 'full' })).equal('yyyy年M月d日EEEE'); + expect(dateFormatter.getLocaleDateTimeFormat('es', false, { dateStyle: 'full' })).equal( + 'EEEE, d de MMMM de yyyy' + ); + expect(dateFormatter.getLocaleDateTimeFormat('ar', false, { dateStyle: 'full' })).equal( + 'EEEE، d MMMM yyyy' + ); + }); + + it('should get correct time formatting for different locales', () => { + expect(dateFormatter.getLocaleDateTimeFormat('en-US', false, { timeStyle: 'short' })).equal('h:mm a'); + expect(dateFormatter.getLocaleDateTimeFormat('en-GB', false, { timeStyle: 'short' })).equal('HH:mm'); + expect(dateFormatter.getLocaleDateTimeFormat('de', false, { timeStyle: 'short' })).equal('HH:mm'); + expect(dateFormatter.getLocaleDateTimeFormat('ja', false, { timeStyle: 'short' })).equal('H:mm'); + expect(dateFormatter.getLocaleDateTimeFormat('es', false, { timeStyle: 'short' })).equal('H:mm'); + expect(dateFormatter.getLocaleDateTimeFormat('ar', false, { timeStyle: 'short' })).equal('h:mm a'); + + expect(dateFormatter.getLocaleDateTimeFormat('en-US', false, { timeStyle: 'medium' })).equal('h:mm:ss a'); + expect(dateFormatter.getLocaleDateTimeFormat('en-GB', false, { timeStyle: 'medium' })).equal('HH:mm:ss'); + expect(dateFormatter.getLocaleDateTimeFormat('de', false, { timeStyle: 'medium' })).equal('HH:mm:ss'); + expect(dateFormatter.getLocaleDateTimeFormat('ja', false, { timeStyle: 'medium' })).equal('H:mm:ss'); + expect(dateFormatter.getLocaleDateTimeFormat('es', false, { timeStyle: 'medium' })).equal('H:mm:ss'); + expect(dateFormatter.getLocaleDateTimeFormat('ar', false, { timeStyle: 'medium' })).equal('h:mm:ss a'); + + expect(dateFormatter.getLocaleDateTimeFormat('en-US', false, { timeStyle: 'long' })).equal('h:mm:ss a z'); + expect(dateFormatter.getLocaleDateTimeFormat('en-GB', false, { timeStyle: 'long' })).equal('HH:mm:ss z'); + expect(dateFormatter.getLocaleDateTimeFormat('de', false, { timeStyle: 'long' })).equal('HH:mm:ss z'); + expect(dateFormatter.getLocaleDateTimeFormat('ja', false, { timeStyle: 'long' })).equal('H:mm:ss z'); + expect(dateFormatter.getLocaleDateTimeFormat('es', false, { timeStyle: 'long' })).equal('H:mm:ss z'); + expect(dateFormatter.getLocaleDateTimeFormat('ar', false, { timeStyle: 'long' })).equal('h:mm:ss a z'); + + expect(dateFormatter.getLocaleDateTimeFormat('en-US', false, { timeStyle: 'full' })).equal( + 'h:mm:ss a zzzz' + ); + expect(dateFormatter.getLocaleDateTimeFormat('en-GB', false, { timeStyle: 'full' })).equal('HH:mm:ss zzzz'); + expect(dateFormatter.getLocaleDateTimeFormat('de', false, { timeStyle: 'full' })).equal('HH:mm:ss zzzz'); + expect(dateFormatter.getLocaleDateTimeFormat('ja', false, { timeStyle: 'full' })).equal('H時mm分ss秒 zzzz'); + expect(dateFormatter.getLocaleDateTimeFormat('es', false, { timeStyle: 'full' })).equal('H:mm:ss (zzzz)'); + expect(dateFormatter.getLocaleDateTimeFormat('ar', false, { timeStyle: 'full' })).equal('h:mm:ss a zzzz'); + }); + + it('should get correct date time formatting for different locales', () => { + expect( + dateFormatter.getLocaleDateTimeFormat('en-US', false, { dateStyle: 'short', timeStyle: 'short' }) + ).equal('M/d/yy, h:mm a'); + expect( + dateFormatter.getLocaleDateTimeFormat('en-GB', false, { dateStyle: 'short', timeStyle: 'short' }) + ).equal('dd/MM/yyyy, HH:mm'); + expect( + dateFormatter.getLocaleDateTimeFormat('ja', false, { dateStyle: 'short', timeStyle: 'short' }) + ).equal('yyyy/MM/dd H:mm'); + + expect( + dateFormatter.getLocaleDateTimeFormat('en-US', false, { dateStyle: 'medium', timeStyle: 'medium' }) + ).equal('MMM d, yyyy, h:mm:ss a'); + expect( + dateFormatter.getLocaleDateTimeFormat('en-GB', false, { dateStyle: 'medium', timeStyle: 'medium' }) + ).equal('d MMM yyyy, HH:mm:ss'); + expect( + dateFormatter.getLocaleDateTimeFormat('ja', false, { dateStyle: 'medium', timeStyle: 'medium' }) + ).equal('yyyy/MM/dd H:mm:ss'); + + expect( + dateFormatter.getLocaleDateTimeFormat('en-US', false, { dateStyle: 'long', timeStyle: 'long' }) + ).equal('MMMM d, yyyy at h:mm:ss a z'); + expect( + dateFormatter.getLocaleDateTimeFormat('en-GB', false, { dateStyle: 'long', timeStyle: 'long' }) + ).equal('d MMMM yyyy at HH:mm:ss z'); + expect(dateFormatter.getLocaleDateTimeFormat('ja', false, { dateStyle: 'long', timeStyle: 'long' })).equal( + 'yyyy年M月d日 H:mm:ss z' + ); + + expect( + dateFormatter.getLocaleDateTimeFormat('en-US', false, { dateStyle: 'full', timeStyle: 'full' }) + ).equal('EEEE, MMMM d, yyyy at h:mm:ss a zzzz'); + expect( + dateFormatter.getLocaleDateTimeFormat('en-GB', false, { dateStyle: 'full', timeStyle: 'full' }) + ).equal('EEEE d MMMM yyyy at HH:mm:ss zzzz'); + expect(dateFormatter.getLocaleDateTimeFormat('ja', false, { dateStyle: 'full', timeStyle: 'full' })).equal( + 'yyyy年M月d日EEEE H時mm分ss秒 zzzz' + ); + }); + }); + + describe('custom date formatting', () => { + it('should return the format for unknown one', () => { + expect(dateFormatter.formatDateCustomFormat(dateTime, 'jjj')).equal('jjj'); + }); + + it('should format era', () => { + let format = 'GG'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('AD'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('сл.Хр.'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('西暦'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('d. C.'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('م'); + + format = 'GGGG'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('Anno Domini'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('след Христа'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('西暦'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('después de Cristo'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('ميلادي'); + + format = 'GGGGG'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('A'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('сл.Хр.'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('AD'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('d. C.'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('م'); + }); + + it('should format year', () => { + let format = 'yy'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('14'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('14'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('14'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('14'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('14'); + + format = 'yyyy'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('2014'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('2014'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('2014'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('2014'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('2014'); + }); + + it('should format iso year', () => { + let format = 'YY'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('14'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('14'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('14'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('14'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('14'); + + format = 'YYYY'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('2014'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('2014'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('2014'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('2014'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('2014'); + }); + + it('should format month', () => { + let format = 'M'; + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'en' })).equal('3'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'bg' })).equal('3'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ja' })).equal('3'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'es' })).equal('3'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ar' })).equal('3'); + + format = 'MM'; + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'en' })).equal('03'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'bg' })).equal('03'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ja' })).equal('03'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'es' })).equal('03'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ar' })).equal('03'); + + format = 'MMM'; + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'en' })).equal('Mar'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'bg' })).equal('03'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ja' })).equal('3'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'es' })).equal('mar'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ar' })).equal('مارس'); + + format = 'MMMM'; + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'en' })).equal('March'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'bg' })).equal('март'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ja' })).equal('3'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'es' })).equal('marzo'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ar' })).equal('مارس'); + + format = 'MMMMM'; + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'en' })).equal('M'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'bg' })).equal('03'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ja' })).equal('3'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'es' })).equal('M'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ar' })).equal('م'); + }); + + it('should format day', () => { + let format = 'd'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('3'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('3'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('3'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('3'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('3'); + + format = 'dd'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('03'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('03'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('03'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('03'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('03'); + }); + + it('should format week day', () => { + let format = 'c'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('Wed'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('ср'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('水'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('mié'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('الأربعاء'); + + format = 'cc'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('Wed'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('ср'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('水'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('mié'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('الأربعاء'); + + format = 'cccc'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('Wednesday'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('сряда'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('水曜日'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('miércoles'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('الأربعاء'); + + format = 'ccccc'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('W'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('с'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('水'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('X'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('ر'); + }); + + it('should format period of the day', () => { + let format = 'a'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('am'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('am'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('am'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('am'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('ص'); + + format = 'aa'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('AM'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('AM'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('AM'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('AM'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('ص'); + + format = 'aaaa'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('AM'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('AM'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('AM'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('AM'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('ص'); + + format = 'aaaaa'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('a'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('a'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('a'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('a'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('ص'); + }); + + it('should format extended period of the day', () => { + let format = 'b'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('at ni.'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('пр. но.'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('夜中'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('de la ma.'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('فج.'); + + format = 'bbbb'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('at night'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('през нощта'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('夜中'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('de la madrugada'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('في الصباح'); + + format = 'bbbbb'; + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'en' })).equal('an'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'bg' })).equal('пн'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ja' })).equal('夜'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'es' })).equal('dlm'); + expect(dateFormatter.formatDateCustomFormat(dateTime, format, { locale: 'ar' })).equal('ف'); + }); + + it('should format hour in 0-12 time format', () => { + let format = 'h'; + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'en' })).equal('4'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'bg' })).equal('4'); + //expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ja' })).equal("4"); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'es' })).equal('4'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ar' })).equal('4'); + + format = 'hh'; + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'en' })).equal('04'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'bg' })).equal('04'); + //expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ja' })).equal("04"); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'es' })).equal('04'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ar' })).equal('04'); + }); + + it('should format hour in 0-24 time format', () => { + let format = 'H'; + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'en-US' })).equal('16'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'en-GB' })).equal('16'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'bg' })).equal('16'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ja' })).equal('16'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'es' })).equal('16'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ar' })).equal('16'); + + format = 'HH'; + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'en-US' })).equal('16'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'en-GB' })).equal('16'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'bg' })).equal('16'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ja' })).equal('16'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'es' })).equal('16'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ar' })).equal('16'); + }); + + it('should format hours at midnight correctly', () => { + const date = new Date('2014-03-21T00:08:09'); + expect(dateFormatter.formatDateCustomFormat(date, 'h')).equal('12'); + expect(dateFormatter.formatDateCustomFormat(date, 'H')).equal('0'); + expect(dateFormatter.formatDateCustomFormat(date, 'K', { locale: 'ja' })).equal('0'); + + expect(dateFormatter.formatDateCustomFormat(date, 'hh')).equal('12'); + expect(dateFormatter.formatDateCustomFormat(date, 'HH')).equal('00'); + expect(dateFormatter.formatDateCustomFormat(date, 'KK', { locale: 'ja' })).equal('00'); + }); + + it('should format minutes', () => { + let format = 'm'; + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'en' })).equal('24'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'bg' })).equal('24'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ja' })).equal('24'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'es' })).equal('24'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ar' })).equal('24'); + + format = 'mm'; + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'en' })).equal('24'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'bg' })).equal('24'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ja' })).equal('24'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'es' })).equal('24'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ar' })).equal('24'); + + format = 'm'; + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'en' })).equal('8'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'bg' })).equal('8'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ja' })).equal('8'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'es' })).equal('8'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ar' })).equal('8'); + + format = 'mm'; + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'en' })).equal('08'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'bg' })).equal('08'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ja' })).equal('08'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'es' })).equal('08'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ar' })).equal('08'); + }); + + it('should format seconds', () => { + let format = 's'; + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'en' })).equal('13'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'bg' })).equal('13'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ja' })).equal('13'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'es' })).equal('13'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ar' })).equal('13'); + + format = 'ss'; + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'en' })).equal('13'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'bg' })).equal('13'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ja' })).equal('13'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'es' })).equal('13'); + expect(dateFormatter.formatDateCustomFormat(dateTime2, format, { locale: 'ar' })).equal('13'); + + format = 's'; + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'en' })).equal('9'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'bg' })).equal('9'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ja' })).equal('9'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'es' })).equal('9'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ar' })).equal('9'); + + format = 'ss'; + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'en' })).equal('09'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'bg' })).equal('09'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ja' })).equal('09'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'es' })).equal('09'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ar' })).equal('09'); + }); + + it('should format fractional seconds', () => { + let format = 'S'; + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'en' })).equal('0'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'bg' })).equal('0'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ja' })).equal('0'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'es' })).equal('0'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ar' })).equal('0'); + + format = 'SS'; + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'en' })).equal('00'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'bg' })).equal('00'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ja' })).equal('00'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'es' })).equal('00'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ar' })).equal('00'); + + format = 'SSS'; + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'en' })).equal('000'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'bg' })).equal('000'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ja' })).equal('000'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'es' })).equal('000'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ar' })).equal('000'); + }); + + it('should format short format timezone', () => { + let format = 'z'; + expect( + dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'en', timezone: 'Etc/GMT+1' }) + ).equal('GMT-1'); + expect( + dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'bg', timezone: 'Etc/GMT+1' }) + ).equal('Гринуич-1'); + expect( + dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ja', timezone: 'Etc/GMT+1' }) + ).equal('GMT-1'); + expect( + dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'es', timezone: 'Etc/GMT+1' }) + ).equal('GMT-1'); + expect( + dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ar', timezone: 'Etc/GMT+1' }) + ).equal('غرينتش-1'); + + format = 'zzzz'; + expect( + dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'en', timezone: 'Etc/GMT+1' }) + ).equal('GMT-01:00'); + expect( + dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'bg', timezone: 'Etc/GMT+1' }) + ).equal('Гринуич-01:00'); + expect( + dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ja', timezone: 'Etc/GMT+1' }) + ).equal('GMT-01:00'); + expect( + dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'es', timezone: 'Etc/GMT+1' }) + ).equal('GMT-01:00'); + expect( + dateFormatter.formatDateCustomFormat(dateTimeHourFull, format, { locale: 'ar', timezone: 'Etc/GMT+1' }) + ).equal('غرينتش-01:00'); + }); + + it('should format combination of single cases', () => { + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, "'ex:' h:mm bbb GGG")).equal( + "'ex:' 4:08 in th. af. AD" + ); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, "'ex:' hh:mm bbb GGG")).equal( + "'ex:' 04:08 in th. af. AD" + ); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, "'ex:' HH:mm bbb GGG")).equal( + "'ex:' 16:08 in th. af. AD" + ); + }); + + it('should log warning regarding week of year format not supported', () => { + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, 'w')).equal('w'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, 'ww')).equal('ww'); + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, 'W')).equal('W'); + }); + + it('should return empty string on empty format', () => { + expect(dateFormatter.formatDateCustomFormat(dateTimeHourFull, '')).equal(''); + }); + }); + + describe('other', () => { + it('should create dates from ISO string correctly', () => { + // Initially in UTC timezone by default + let dateString = '2025-01-01'; + let expectedUTCDate = new Date(dateString); + let expectedConverted = dateFormatter.createDateFromValue(dateString); + + // The timezone of the machine. For UTC+0 would be 0 + const timeZoneOffsetMin = expectedUTCDate.getTimezoneOffset() * 1000 * 60; + // Value for zero hour check. If the timezone offset is 0, switch it to something else so it still does not equal + const zeroHourExUTC = timeZoneOffsetMin === 0 ? 1 : 0; + + // Result should be in local timezone but it's not, so there's difference + expect(expectedUTCDate.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getHours()).toEqual(0); + expect(expectedConverted.getTime() - expectedUTCDate.getTime()).equal(timeZoneOffsetMin); + + dateString = '2025-01-01T00:00Z'; + expectedUTCDate = new Date(dateString); + expectedConverted = dateFormatter.createDateFromValue(dateString); + expect(expectedUTCDate.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getTime() - expectedUTCDate.getTime()).equal(0); + + dateString = '2025-01-01T00:00:00Z'; + expectedUTCDate = new Date(dateString); + expectedConverted = dateFormatter.createDateFromValue(dateString); + expect(expectedUTCDate.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getTime() - expectedUTCDate.getTime()).equal(0); + + dateString = '2025-01-01T00:00+00:00'; + expectedUTCDate = new Date(dateString); + expectedConverted = dateFormatter.createDateFromValue(dateString); + expect(expectedUTCDate.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getTime() - expectedUTCDate.getTime()).equal(0); + + dateString = '2025-01'; + expectedUTCDate = new Date(dateString); + expectedConverted = dateFormatter.createDateFromValue(dateString); + // Result should be in local timezone but it's not, so there's difference + expect(expectedUTCDate.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getHours()).toEqual(0); + expect(expectedConverted.getTime() - expectedUTCDate.getTime()).equal(timeZoneOffsetMin); + + dateString = '2025-01T00:00Z'; + expectedUTCDate = new Date(dateString); + expectedConverted = dateFormatter.createDateFromValue(dateString); + expect(expectedUTCDate.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getTime() - expectedUTCDate.getTime()).equal(0); + + dateString = '2025-01T00:00:00Z'; + expectedUTCDate = new Date(dateString); + expectedConverted = dateFormatter.createDateFromValue(dateString); + expect(expectedUTCDate.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getTime() - expectedUTCDate.getTime()).equal(0); + + dateString = '2025-01T00:00+00:00'; + expectedUTCDate = new Date(dateString); + expectedConverted = dateFormatter.createDateFromValue(dateString); + expect(expectedUTCDate.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getTime() - expectedUTCDate.getTime()).equal(0); + + dateString = '2025-01T00:00:00+00:00'; + expectedUTCDate = new Date(dateString); + expectedConverted = dateFormatter.createDateFromValue(dateString); + expect(expectedUTCDate.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getTime() - expectedUTCDate.getTime()).equal(0); + + // Initially in local timezone + dateString = '2025-01-01T00:00:00'; + let expectedLocalTime = new Date(dateString); + expectedConverted = dateFormatter.createDateFromValue(dateString); + expect(expectedLocalTime.getHours()).toEqual(0); + expect(expectedConverted.getHours()).toEqual(0); + expect(expectedConverted.getTime() - expectedLocalTime.getTime()).equal(0); + + dateString = '2025-01-01T00:00:00.000'; + expectedLocalTime = new Date(dateString); + expectedConverted = dateFormatter.createDateFromValue(dateString); + expect(expectedLocalTime.getHours()).toEqual(0); + expect(expectedConverted.getHours()).toEqual(0); + expect(expectedConverted.getTime() - expectedLocalTime.getTime()).equal(0); + + dateString = '2025-01T00:00:00'; + expectedLocalTime = new Date(dateString); + expectedConverted = dateFormatter.createDateFromValue(dateString); + expect(expectedLocalTime.getHours()).toEqual(0); + expect(expectedConverted.getHours()).toEqual(0); + expect(expectedConverted.getTime() - expectedLocalTime.getTime()).equal(0); + + dateString = '2025-01T00:00:00.000'; + expectedLocalTime = new Date(dateString); + expectedConverted = dateFormatter.createDateFromValue(dateString); + expect(expectedLocalTime.getHours()).toEqual(0); + expect(expectedConverted.getHours()).toEqual(0); + expect(dateFormatter.createDateFromValue(dateString).getTime() - expectedLocalTime.getTime()).equal(0); + }); + + it('should create dates from other regular valid string formats', () => { + let dateString = 'January 1, 2025'; + let expectedUTCDate = new Date(dateString); + let expectedConverted = dateFormatter.createDateFromValue(dateString); + + // Result should be in local timezone but it's not, so there's difference + expect(expectedUTCDate.getHours()).toEqual(0); + expect(expectedConverted.getHours()).toEqual(0); + expect(expectedConverted.getTime() - expectedUTCDate.getTime()).equal(0); + + dateString = 'January 1, 2025 00:00'; + expectedUTCDate = new Date(dateString); + expectedConverted = dateFormatter.createDateFromValue(dateString); + expect(expectedUTCDate.getHours()).toEqual(0); + expect(expectedConverted.getHours()).toEqual(0); + expect(expectedConverted.getTime() - expectedUTCDate.getTime()).equal(0); + + // The timezone of the machine. For UTC+0 would be 0 + const timeZoneOffsetMin = expectedUTCDate.getTimezoneOffset() * 1000 * 60; + // Value for zero hour check. If the timezone offset is 0, switch it to something else so it still does not equal + const zeroHourExUTC = timeZoneOffsetMin === 0 ? 1 : 0; + + dateString = 'January 1, 2025 00:00 UTC'; + expectedUTCDate = new Date(dateString); + expectedConverted = dateFormatter.createDateFromValue(dateString); + expect(expectedUTCDate.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getHours()).not.toEqual(zeroHourExUTC); + expect(expectedConverted.getTime() - expectedUTCDate.getTime()).equal(0); + }); + }); +}); diff --git a/projects/igniteui-i18n-core/src/formatters/date.formatter.ts b/projects/igniteui-i18n-core/src/formatters/date.formatter.ts new file mode 100644 index 0000000..b552ba4 --- /dev/null +++ b/projects/igniteui-i18n-core/src/formatters/date.formatter.ts @@ -0,0 +1,488 @@ +import type { ICustomFormatOptions } from '../i18n-manager.interfaces.js'; +import { customFormatRegex, isoRegex } from '../utils.js'; +import { BaseFormatter } from './base.formatter.js'; +import type { LocaleFormatter } from './locale.formatter.js'; + +export class DateFormatter extends BaseFormatter { + public defaultCustomFormatOptions: ICustomFormatOptions = { + forceLeadingZero: false, + timezone: 'GMT' + }; + private localeFormatter: LocaleFormatter; + + constructor(defaultLocale: string, localeFormatter: LocaleFormatter) { + super(defaultLocale, Intl.DateTimeFormat); + this.localeFormatter = localeFormatter; + this.defaultOptions = {}; + } + + /** + * Transform string or number representation of a date time to a Date object + * @param value Can be any string or number representation of a date, supported by the JS Date object. + * @returns The date as a Date object. + */ + public createDateFromValue(value: string | number) { + if (typeof value === 'string') { + // Workaround for ISO date without time or specified UTC explicitly + const match = isoRegex.exec(value); + if (match && !match.groups?.time && !match.groups?.UTC) { + value += 'T00:00:00'; + } + } + return new Date(value); + } + + /** + * Format a date object or date number using Intl. + * @param value Value to be formatted + * @param locale Override of the current global locale. + * @param options Options by which to format the date. + * @returns String representing the formatted value. + */ + public formatDateTime(value: Date | number, locale?: string, options?: Intl.DateTimeFormatOptions) { + const formatter = this.getIntlFormatter(locale, options); + return formatter.format(value); + } + + /** + * Format a date object or date number using Intl. + * @param value Value to be formatted + * @param locale Override of the current global locale. + * @param options Options by which to format the date. + * @returns Array of strings representing the formatted value, separated in parts. + */ + public formatDateTimeToParts(value: Date | number, locale?: string, options?: Intl.DateTimeFormatOptions) { + const formatter = this.getIntlFormatter(locale, options); + return formatter.formatToParts(value); + } + + /** + * Get the format of a date, based on the options provided. + * If you want to get only date format, set `dateStyle` for example. For time only format set `timeStyle` or for both date and time set both `dateStyle` and `timeStyle`. + * @param locale + * @param dateTimeOptions + * @returns + */ + public getLocaleDateTimeFormat( + locale: string, + forceLeadingZero = false, + dateTimeOptions?: Intl.DateTimeFormatOptions + ) { + // Use any date with single digit for values so later on we can determine if the are '2-digit' or 'numeric' + const testDate = new Date(2015, 2, 8, 1, 2, 4); + const formatter = this.getIntlFormatter(locale, dateTimeOptions); + const resultParts = formatter.formatToParts(testDate); + let resultFormat = ''; + for (const part of resultParts) { + if (part.type === 'weekday') { + resultFormat += 'EEEE'; + } else if (part.type === 'day') { + if (part.value.length === 1 && !forceLeadingZero) { + resultFormat += 'd'; + } else { + resultFormat += 'dd'; + } + } else if (part.type === 'month') { + const valueLength = part.value.length; + if (Number.parseInt(part.value, 10)) { + resultFormat += part.value.length === 1 && !forceLeadingZero ? 'M' : 'MM'; + } else if (1 < valueLength && valueLength < 4) { + resultFormat += 'MMM'; + } else if (valueLength >= 4) { + resultFormat += 'MMMM'; + } else if (valueLength === 1) { + // Possibly not used by anyone by default + resultFormat += 'MMMMM'; + } + } else if (part.type === 'year') { + if (part.value.length === 2) { + resultFormat += 'yy'; + } else { + resultFormat += 'yyyy'; + } + } else if (part.type === 'hour') { + // h24 doesn't seem to be used anywhere + // eslint-disable-next-line + const hourCycle = (this.localeFormatter.getIntlFormatter(locale) as any).hourCycles[0]; + let replaceHour = 'H'; + if (hourCycle === 'h11') { + // Should be used by Japan, but it returns h12 for them. + replaceHour = 'K'; + } else if (hourCycle === 'h12') { + replaceHour = 'h'; + } + replaceHour += part.value.length === 1 && forceLeadingZero ? replaceHour : ''; + resultFormat += part.value.replaceAll(/\d/g, replaceHour); + } else if (part.type === 'minute') { + resultFormat += part.value.length === 1 && !forceLeadingZero ? 'm' : 'mm'; + } else if (part.type === 'second') { + resultFormat += part.value.length === 1 && !forceLeadingZero ? 's' : 'ss'; + } else if (part.type === 'dayPeriod') { + resultFormat += 'a'; + } else if (part.type === 'timeZoneName') { + const shortParts = this.getIntlFormatter(locale, { + timeZoneName: 'short' + }).formatToParts(testDate); + const shortTimezone = this.findDatePart(shortParts, 'timeZoneName'); + resultFormat += part.value === shortTimezone ? 'z' : 'zzzz'; + } else if (part.type === 'literal') { + resultFormat += part.value; + } + } + return resultFormat; + } + + /** + * Get the first day of a week numbered 1(Monday)...7(Sunday) based on the current locale or a provided one. + * Note: There's no support for Firefox currently, so by default it returns 1. + * @param locale Locale for which to get the day of week. Otherwise use current globally set. + * @returns The first day of the week. + */ + public getFirstDayOfWeek(locale?: string): number { + const formatter = this.localeFormatter.getIntlFormatter(locale); + let firstDay = 1; + // Missing some typescript definitions for Int.Locale. Disable lint for now until this is merged: https://github.com/microsoft/TypeScript/pull/58084 + /* eslint-disable */ + if ((formatter as any).getWeekInfo) { + // Firefox currently doesn't support getWeekInfo, default to Monday in this case. + firstDay = (formatter as any).getWeekInfo().firstDay; + } + /* eslint-enable */ + return firstDay; + } + + /** + * Use custom formatting to format a date to match the provided strings. + * Currently supported values are G, y, Y, m, M, L, d, E, c, a, b, B, h, H, K, s, S, z, Z, O: + * + * Date: + * c, cc, ccc, cccc, ccccc - shows weekday in different lengths. Alias - `E` + * d, dd - shows day of month in numeric (m) or 2-digit/zero padded (mm) style. + * M, MM, MMM, MMMM, MMMMM - show month of the year as number(M, MM) or as a name (MMM, MMMM, MMMMM). Alias - `L`. + * y, yy, yyy, yyyy, yyyyy - show year in different lengths. + * Y, YY, YYY, YYYY, YYYYY - show year in different lengths based on iso8601 calendar. + * G, GG, GGG, GGGG, GGGGG - shows era in different lengths + * + * Time: + * m, mm - shows minutes in numeric(m) or 2-digit/zero padded (mm) style. + * h, hh - shows hour using 12h clock in numeric(m) or 2-digit/zero padded (mm) style. + * H, HH - shows hour using 24h clock in numeric(m) or 2-digit/zero padded (mm) style. + * K, KK - shows hour using 12h clock where midnight is 0:00 instead of 12:00 in numeric(m) or 2-digit/zero padded (mm) style. + * s, ss - shows seconds in numeric(m) or 2-digit/zero padded (mm) style. + * S, SS, SSS - shows fractional seconds in different fraction. + * a, aa, aaa, aaaa, aaaaa - shows period of time in short format like a/p/am/AM/pm/PM. Alias - 't' + * b, bb, bbb, bbbb, bbbbb - shows extended period of time like midnight, at night, noon and etc. Alias - `B` + * z, zz, zzz, zzzz, zzzzz - shows timezone in short (z, zz, zzz, zzzzz) or long (zzzz) format. Aliases - `Z` and `O` + * @param value Date to be formatted + * @param format String containing custom strings describing how the date should be formatted + * @param options Options for the custom formatting like locale, timezone or force 2-digits always where applicable. + * @returns + */ + public formatDateCustomFormat(value: Date, format: string, options?: ICustomFormatOptions) { + let parts: string[] = []; + let match: RegExpExecArray | null; + while (format) { + match = customFormatRegex.exec(format); + if (match) { + parts = parts.concat(match.slice(1)); + const part = parts.pop(); + if (!part) { + break; + } + format = part; + } else { + parts.push(format); + break; + } + } + + const formatOptions = Object.assign({}, this.defaultCustomFormatOptions, options); + let dateText = ''; + for (const part of parts) { + dateText += this.formatPartialDateValue(value, part, formatOptions); + } + return dateText; + } + + private formatPartialDateValue(date: Date, format: string, formatOptions: ICustomFormatOptions) { + const numericOption = formatOptions.forceLeadingZero ? '2-digit' : 'numeric'; + const options: Intl.DateTimeFormatOptions = {}; + let periodStyle: 'narrow' | 'short' | 'medium' | 'long' | undefined; + switch (format) { + case 'G': + case 'GG': + case 'GGG': + options.era = 'short'; + break; + case 'GGGG': + options.era = 'long'; + break; + case 'GGGGG': + options.era = 'narrow'; + break; + case 'yy': + options.year = '2-digit'; + break; + case 'y': + case 'yyy': + case 'yyyy': + options.year = 'numeric'; + break; + + case 'YY': + options.year = '2-digit'; + options.calendar = 'iso8601'; + break; + case 'Y': + case 'YYY': + case 'YYYY': + options.year = 'numeric'; + options.calendar = 'iso8601'; + break; + + case 'M': + case 'L': + options.month = numericOption; + break; + case 'MM': + case 'LL': + options.month = '2-digit'; + break; + + // Month of the year (January, ...), string, format + case 'MMM': + case 'LLL': + options.month = 'short'; + break; + case 'MMMM': + case 'LLLL': + options.month = 'long'; + break; + case 'MMMMM': + case 'LLLLL': + options.month = 'narrow'; + break; + + //Deprecated. + // Week of the year (1, ... 52) + case 'w': + case 'ww': + // Week of the month (1, ...) + // falls through + case 'W': + console.warn( + 'Week of the year and week of the month has been deprecated for Ignite UI. Please use custom formatting.' + ); + return format; + + // Day of the month (1-31) + case 'd': + options.day = numericOption; + break; + case 'dd': + options.day = '2-digit'; + break; + + // Day of the Week + case 'c': + case 'cc': + case 'ccc': + case 'cccccc': + case 'E': + case 'EE': + case 'EEE': + case 'EEEEEE': + options.weekday = 'short'; + break; + case 'cccc': + case 'EEEE': + options.weekday = 'long'; + break; + case 'ccccc': + case 'EEEEE': + options.weekday = 'narrow'; + break; + // Generic period of the day (am-pm) + // am/pm + case 'a': + case 't': + periodStyle = 'short'; + options.timeStyle = 'short'; + break; + // AM/PM + case 'aa': + case 'aaa': + case 'tt': + case 'ttt': + periodStyle = 'medium'; + options.timeStyle = 'short'; + break; + case 'aaaa': + case 'tttt': + periodStyle = 'long'; + options.timeStyle = 'short'; + break; + // a/p + case 'aaaaa': + case 'ttttt': + periodStyle = 'narrow'; + options.timeStyle = 'short'; + break; + + // Extended period of the day (midnight, at night, ...), standalone + case 'b': + case 'bb': + case 'bbb': + case 'B': + case 'BB': + case 'BBB': + options.dayPeriod = 'short'; + break; + case 'bbbb': + case 'BBBB': + options.dayPeriod = 'long'; + break; + case 'bbbbb': + case 'BBBBB': + options.dayPeriod = 'narrow'; + break; + + // Hour in AM/PM, (1-12) + case 'h': + options.hour12 = true; + options.hour = numericOption; + break; + case 'hh': + options.hour12 = true; + options.hour = '2-digit'; + break; + + // Hour of the day (0-23) + case 'H': + options.hour12 = false; + options.hour = numericOption; + break; + // Hour in day, padded (00-23) + case 'HH': + options.hour12 = false; + options.hour = '2-digit'; + break; + + case 'K': + options.hourCycle = 'h11'; + options.hour = numericOption; + break; + case 'KK': + options.hourCycle = 'h11'; + options.hour = '2-digit'; + break; + + // Minute of the hour (0-59) + case 'm': + options.minute = numericOption; + break; + case 'mm': + // Also for some reason this is not working in Intl for all locales ?? + options.minute = '2-digit'; + break; + + // Second of the minute (0-59) + case 's': + options.second = numericOption; + break; + case 'ss': + // Also for some reason this is not working in Intl for all locales ?? + options.second = '2-digit'; + break; + case 'S': + options.fractionalSecondDigits = 1; + break; + case 'SS': + options.fractionalSecondDigits = 2; + break; + case 'SSS': + options.fractionalSecondDigits = 3; + break; + // Timezone short format (GMT+4) + case 'O': + case 'OO': + case 'OOO': + case 'z': + case 'zz': + case 'zzz': + case 'Z': + case 'ZZ': + case 'ZZZ': + options.timeZone = formatOptions.timezone; + options.timeZoneName = 'short'; + break; + // Timezone long format (GMT+0430) + case 'OOOO': + case 'zzzz': + case 'ZZZZ': + options.timeZone = formatOptions.timezone; + options.timeZoneName = 'long'; + break; + default: + return format; + } + const dateParts = this.formatDateTimeToParts(date, formatOptions.locale, options); + if (options.era) { + return this.findDatePart(dateParts, 'era'); + } else if (periodStyle || options.dayPeriod) { + let value = dateParts.find((part) => part.type === 'dayPeriod')?.value; + if (!value && periodStyle) { + // Current locale doesn't have generic day period. Just use the `en` one. + value = this.findDatePart(this.formatDateTimeToParts(date, 'en', options), 'dayPeriod'); + } + switch (periodStyle ?? options.dayPeriod) { + case 'narrow': + return value + ?.split(' ') + .map((part) => part.substring(0, 1).toLocaleLowerCase()) + .join(''); + case 'short': + return value + ?.split(' ') + .map((part) => part.substring(0, 2).toLocaleLowerCase() + (part.length > 2 ? '.' : '')) + .join(' '); + case 'medium': + return value + ?.split(' ') + .map((part) => part.substring(0, 2) + (part.length > 2 ? '.' : '')) + .join(' '); + default: + return value; + } + } else if (options.hour) { + const value = this.findDatePart(dateParts, 'hour'); + if ( + !formatOptions.forceLeadingZero && + options.hour === 'numeric' && + value?.startsWith('0') && + value.length === 2 + ) { + // Use numeric option value to format to shorter hour. Ex: instead of 08 return 8. + return value[1]; + } + return value; + } else if (options.minute === '2-digit') { + // For some reason not working as expected in Intl + const minutes = this.findDatePart(dateParts, 'minute'); + return minutes?.length === 1 ? '0' + minutes : minutes; + } else if (options.second === '2-digit') { + // For some reason not working as expected in Intl + const seconds = this.findDatePart(dateParts, 'second'); + return seconds?.length === 1 ? '0' + seconds : seconds; + } else if (options.timeZone) { + return this.findDatePart(dateParts, 'timeZoneName'); + } else if (options.fractionalSecondDigits) { + return this.findDatePart(dateParts, 'fractionalSecond'); + } + return dateParts[0].value; + } + + private findDatePart(parts: Intl.DateTimeFormatPart[], partName: string) { + return parts.find((part) => part.type === partName)?.value; + } +} diff --git a/projects/igniteui-i18n-core/src/formatters/display-names.formatter.spec.ts b/projects/igniteui-i18n-core/src/formatters/display-names.formatter.spec.ts new file mode 100644 index 0000000..9926349 --- /dev/null +++ b/projects/igniteui-i18n-core/src/formatters/display-names.formatter.spec.ts @@ -0,0 +1,33 @@ +import { describe, expect, it } from 'vitest'; +import { DateFormatter } from './date.formatter.js'; +import { DisplayNamesFormatter } from './display-names.formatter.js'; +import { LocaleFormatter } from './locale.formatter.js'; + +describe('display names formatting', () => { + const localeFormatter = new LocaleFormatter('en'); + const dateFormatter = new DateFormatter('en', localeFormatter); + const displayNamesFormatter = new DisplayNamesFormatter('en', dateFormatter); + + it('should return correct week labels per locale', () => { + //narrow + expect(displayNamesFormatter.getWeekLabel('en', { style: 'narrow' })).equal('W'); + expect(displayNamesFormatter.getWeekLabel('bg', { style: 'narrow' })).equal('с'); + expect(displayNamesFormatter.getWeekLabel('ja', { style: 'narrow' })).equal('週'); + expect(displayNamesFormatter.getWeekLabel('es', { style: 'narrow' })).equal('S'); + expect(displayNamesFormatter.getWeekLabel('ar', { style: 'narrow' })).equal('ا'); + + //short + expect(displayNamesFormatter.getWeekLabel('en', { style: 'short' })).equal('Wk.'); + expect(displayNamesFormatter.getWeekLabel('bg', { style: 'short' })).equal('седм.'); + expect(displayNamesFormatter.getWeekLabel('ja', { style: 'short' })).equal('週'); + expect(displayNamesFormatter.getWeekLabel('es', { style: 'short' })).equal('Sem.'); + expect(displayNamesFormatter.getWeekLabel('ar', { style: 'short' })).equal('الأسبوع'); + + //long + expect(displayNamesFormatter.getWeekLabel('en', { style: 'long' })).equal('Week'); + expect(displayNamesFormatter.getWeekLabel('bg', { style: 'long' })).equal('седмица'); + expect(displayNamesFormatter.getWeekLabel('ja', { style: 'long' })).equal('週'); + expect(displayNamesFormatter.getWeekLabel('es', { style: 'long' })).equal('Semana'); + expect(displayNamesFormatter.getWeekLabel('ar', { style: 'long' })).equal('الأسبوع'); + }); +}); diff --git a/projects/igniteui-i18n-core/src/formatters/display-names.formatter.ts b/projects/igniteui-i18n-core/src/formatters/display-names.formatter.ts new file mode 100644 index 0000000..b8f8c2e --- /dev/null +++ b/projects/igniteui-i18n-core/src/formatters/display-names.formatter.ts @@ -0,0 +1,33 @@ +import { mergeOptions } from '../utils.js'; +import { BaseFormatter } from './base.formatter.js'; +import type { DateFormatter } from './date.formatter.js'; + +export class DisplayNamesFormatter extends BaseFormatter { + private dateFormatter: DateFormatter; + + constructor(defaultLocale: string, dateFormatter: DateFormatter) { + super(defaultLocale, Intl.DisplayNames); + this.dateFormatter = dateFormatter; + } + + public getWeekLabel(locale?: string, options?: Partial) { + const requiredOptions: Intl.DisplayNamesOptions = { + type: 'dateTimeField' + }; + const combinedOptions = options ? mergeOptions(options, requiredOptions) : requiredOptions; + const formatter = this.getIntlFormatter(locale, combinedOptions as Intl.DisplayNamesOptions); + const weekDay = this.dateFormatter + .formatDateTimeToParts(new Date(), locale, { weekday: 'narrow' }) + .find((part) => part.type === 'weekday')?.value; + + let weekLabel = formatter.of('weekOfYear'); + if (weekLabel && weekDay?.startsWith(weekDay[0].toUpperCase())) { + weekLabel = weekLabel[0].toUpperCase() + weekLabel?.substring(1); + } + + if (options?.style === 'narrow') { + return weekLabel?.substring(0, 1) ?? ''; + } + return weekLabel ?? ''; + } +} diff --git a/projects/igniteui-i18n-core/src/formatters/locale.formatter.ts b/projects/igniteui-i18n-core/src/formatters/locale.formatter.ts new file mode 100644 index 0000000..128a58a --- /dev/null +++ b/projects/igniteui-i18n-core/src/formatters/locale.formatter.ts @@ -0,0 +1,7 @@ +import { BaseFormatter } from './base.formatter.js'; + +export class LocaleFormatter extends BaseFormatter { + constructor(defaultLocale: string) { + super(defaultLocale, Intl.Locale); + } +} diff --git a/projects/igniteui-i18n-core/src/formatters/number.formatter.spec.ts b/projects/igniteui-i18n-core/src/formatters/number.formatter.spec.ts new file mode 100644 index 0000000..9d3333d --- /dev/null +++ b/projects/igniteui-i18n-core/src/formatters/number.formatter.spec.ts @@ -0,0 +1,104 @@ +import { describe, expect, it } from 'vitest'; +import { NumberFormatter } from './number.formatter.js'; + +describe('number formatting', () => { + const numberFormatter = new NumberFormatter('en'); + + it('should format regular numbers with provided manual locale', () => { + expect(numberFormatter.formatNumber(12345, 'en')).equal('12,345'); + expect(numberFormatter.formatNumber(12345, 'de')).equal('12.345'); + expect(numberFormatter.formatNumber(12345, 'bg')).equal('12 345'); + expect(numberFormatter.formatNumber(12345, 'ja')).equal('12,345'); + expect(numberFormatter.formatNumber(12345, 'es')).equal('12.345'); + expect(numberFormatter.formatNumber(12345, 'pl')).equal('12 345'); + }); + + it('should format regular numbers when locale is changed through api', () => { + expect(numberFormatter.formatNumber(12345, 'en')).equal('12,345'); + + numberFormatter.onLocaleChange('de'); + expect(numberFormatter.formatNumber(12345)).equal('12.345'); + + numberFormatter.onLocaleChange('bg'); + expect(numberFormatter.formatNumber(12345)).equal('12 345'); + + numberFormatter.onLocaleChange('ja'); + expect(numberFormatter.formatNumber(12345)).equal('12,345'); + + numberFormatter.onLocaleChange('es'); + expect(numberFormatter.formatNumber(12345)).equal('12.345'); + + numberFormatter.onLocaleChange('pl'); + expect(numberFormatter.formatNumber(12345)).equal('12 345'); + }); + + it('should format numbers with provided currency settings for the same currency', () => { + const currencyOption: Intl.NumberFormatOptions = { + style: 'currency', + currency: 'EUR', + maximumFractionDigits: 0 + }; + + expect(numberFormatter.formatNumber(12345, 'en', currencyOption)).equal('€12,345'); + expect(numberFormatter.formatNumber(12345, 'de', currencyOption)).equal('12.345 €'); + expect(numberFormatter.formatNumber(12345, 'bg', currencyOption)).equal('12 345 €'); + expect(numberFormatter.formatNumber(12345, 'ja', currencyOption)).equal('€12,345'); + expect(numberFormatter.formatNumber(12345, 'es', currencyOption)).equal('12.345 €'); + expect(numberFormatter.formatNumber(12345, 'pl', currencyOption)).equal('12 345 €'); + }); + + it('should format numbers with provided currency settings for different currencies', () => { + expect( + numberFormatter.formatNumber(12345, 'en-GB', { + style: 'currency', + currency: 'GBP' + }) + ).equal('£12,345.00'); + expect( + numberFormatter.formatNumber(12345, 'bg', { + style: 'currency', + currency: 'BGN' + }) + ).equal('12 345,00 лв.'); + expect( + numberFormatter.formatNumber(12345, 'ja', { + style: 'currency', + currency: 'JPY' + }) + ).equal('¥12,345'); + expect( + numberFormatter.formatNumber(12345, 'es', { + style: 'currency', + currency: 'EUR' + }) + ).equal('12.345,00 €'); + expect( + numberFormatter.formatNumber(12345, 'pl', { + style: 'currency', + currency: 'PLN' + }) + ).equal('12 345,00 zł'); + }); + + it('should get correct currency symbol position', () => { + expect(numberFormatter.getCurrencyPosition('en')).equal(0); + expect(numberFormatter.getCurrencyPosition('bg')).equal(2); + expect(numberFormatter.getCurrencyPosition('ja')).equal(0); + expect(numberFormatter.getCurrencyPosition('es')).equal(2); + expect(numberFormatter.getCurrencyPosition('pl')).equal(2); + }); + + it('should get correct currency symbol when provided currency name', () => { + expect(numberFormatter.getCurrencySymbol('GBP', 'en', 'symbol')).equal('£'); + expect(numberFormatter.getCurrencySymbol('BGN', 'bg', 'symbol')).equal('лв.'); + expect(numberFormatter.getCurrencySymbol('JPY', 'ja', 'symbol')).equal('¥'); + expect(numberFormatter.getCurrencySymbol('EUR', 'es', 'symbol')).equal('€'); + expect(numberFormatter.getCurrencySymbol('PLN', 'pl', 'symbol')).equal('zł'); + + expect(numberFormatter.getCurrencySymbol('GBP', 'en', 'name')).equal('British pounds'); + expect(numberFormatter.getCurrencySymbol('BGN', 'bg', 'name')).equal('български лева'); + expect(numberFormatter.getCurrencySymbol('JPY', 'ja', 'name')).equal('円'); + expect(numberFormatter.getCurrencySymbol('EUR', 'es', 'name')).equal('euros'); + expect(numberFormatter.getCurrencySymbol('PLN', 'pl', 'name')).equal('złotych polskich'); + }); +}); diff --git a/projects/igniteui-i18n-core/src/formatters/number.formatter.ts b/projects/igniteui-i18n-core/src/formatters/number.formatter.ts new file mode 100644 index 0000000..3758420 --- /dev/null +++ b/projects/igniteui-i18n-core/src/formatters/number.formatter.ts @@ -0,0 +1,59 @@ +import { BaseFormatter } from './base.formatter.js'; + +export class NumberFormatter extends BaseFormatter { + constructor(defaultLocale: string) { + super(defaultLocale, Intl.NumberFormat); + this.defaultOptions = { + maximumFractionDigits: 3 + }; + } + + /** + * Format a number using Intl. + * @param value Value to be formatted. + * @param locale Override of the current global locale. + * @param options Options by which to format the number. + * @returns Formatted value. + */ + public formatNumber(value: number, locale?: string, options?: Intl.NumberFormatOptions) { + const formatter = this.getIntlFormatter(locale, options); + return formatter.format(value); + } + + /** + * Get the currency symbol for provided currency code. + * @param currencyCode The currency code to get the symbol of. + * @param currencyDisplay How should the currency code be rendered. + * @param locale Override locale instead of the current one. + * @returns String representation of the currency symbol. + */ + public getCurrencySymbol( + currencyCode: string, + locale?: string, + currencyDisplay?: keyof Intl.NumberFormatOptionsCurrencyDisplayRegistry + ) { + const options: Intl.NumberFormatOptions = { + style: 'currency', + currency: currencyCode, + currencyDisplay: currencyDisplay, + maximumFractionDigits: 0 + }; + const formatter = this.getIntlFormatter(locale, options); + return formatter.formatToParts(0).find((part) => part.type === 'currency')?.value; + } + + /** + * Get the currency symbol/name position in formatted value. + * @param locale Override locale instead of the current one. + * @returns Position of the symbol for number 0. + */ + public getCurrencyPosition(locale?: string) { + const options: Intl.NumberFormatOptions = { + style: 'currency', + currency: 'USD', + maximumFractionDigits: 0 + }; + const formatter = this.getIntlFormatter(locale, options); + return formatter.formatToParts(0).findIndex((part) => part.type === 'currency'); + } +} diff --git a/projects/igniteui-i18n-core/src/i18n-manager.interfaces.ts b/projects/igniteui-i18n-core/src/i18n-manager.interfaces.ts new file mode 100644 index 0000000..10a22d0 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n-manager.interfaces.ts @@ -0,0 +1,80 @@ +/** i18n manager ResourceChange event typings */ +export interface IResourceChangeEventArgs { + oldLocale: string; + newLocale: string; +} + +export interface ICustomFormatOptions { + forceLeadingZero?: boolean; + locale?: string; + timezone?: string; +} + +export interface I18nManagerEventMap { + onResourceChange: CustomEvent; +} + +type CustomEventListener = (evt: T) => void; +export interface CustomEventListenerObject { + handleEvent(object: T): void; +} +type CustomEventListenerOrEventListenerObject = CustomEventListener | CustomEventListenerObject; + +interface IManagerEventTarget extends EventTarget { + addEventListener( + type: K, + listener: CustomEventListenerOrEventListenerObject, + options?: boolean | EventListenerOptions + ): void; + addEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | EventListenerOptions + ): void; + removeEventListener( + type: K, + listener: CustomEventListenerOrEventListenerObject, + options?: boolean | EventListenerOptions + ): void; + removeEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | EventListenerOptions + ): void; + dispatchEvent(event: I18nManagerEventMap[K]): boolean; +} + +export const I18nManagerEventTarget = EventTarget as { + prototype: IManagerEventTarget; + new (): IManagerEventTarget; +}; + +export interface IIgI18nManager extends IManagerEventTarget { + defaultLocale: string; + currentLocale: string; +} + +/** Formatter types implemented */ +export const Formatter = { + Date: 'Date', + DisplayNames: 'DisplayNames', + Locale: 'Locale', + Number: 'Number' +} as const; + +export type Formatter = keyof typeof Formatter; + +/** Generic type for any Intl formatter that can be instantiated */ +export type IntlFormatter = + | (new (locale: string | Intl.Locale, options?: O) => T) + | (new (locale: Intl.LocalesArgument, options: O) => T); + +/** Generic type for currently implemented formatter interfaces */ +export type I18nFormatter = Intl.DateTimeFormat | Intl.NumberFormat | Intl.Locale | Intl.DisplayNames; + +/** Generic type for currently implemented formatter interfaces */ +export type I18nFormatterOptions = Intl.DateTimeFormatOptions | Intl.NumberFormatOptions | Intl.LocaleOptions; + +export type PrefixedResourceStrings = { + [P in keyof T as P extends string ? `${Q}${P}` : never]?: string; +}; diff --git a/projects/igniteui-i18n-core/src/i18n-manager.spec.ts b/projects/igniteui-i18n-core/src/i18n-manager.spec.ts new file mode 100644 index 0000000..98cfd50 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n-manager.spec.ts @@ -0,0 +1,198 @@ +import { ActionStripResourceStringsBG, ActionStripResourceStringsES } from 'igniteui-i18n-resources'; +import { beforeEach, describe, expect, it } from 'vitest'; +import { ActionStripResourceStringsEN } from './i18n/EN/action-strip-resources.js'; +import type { IResourceChangeEventArgs } from './i18n-manager.interfaces.js'; +import { + getCurrentI18n, + getCurrentResourceStrings, + getI18nManager, + I18nManager, + registerI18n, + setCurrentI18n +} from './i18n-manager.js'; +import { wait } from './test-utils.js'; + +describe('i18n tests', () => { + let manager: I18nManager; + beforeEach(() => { + // Create separate manage for each tests, so it's state is reset for each test. + manager = new (I18nManager as any)(); + }); + + describe('public api', () => { + it('should initialize correct instance of manager', () => { + const publicManager = getI18nManager(); + expect(publicManager?.currentLocale).equal('en-US'); + + //For empty resources returns {} + expect(JSON.stringify(getCurrentResourceStrings())).equals(JSON.stringify({})); + }); + + it('should set correct locale', () => { + expect(getCurrentI18n()).toEqual('en-US'); + + setCurrentI18n('bg'); + expect(getCurrentI18n()).toEqual('bg'); + }); + + it('should register and return correct resource strings', () => { + registerI18n(ActionStripResourceStringsEN, 'en-US'); + + const resources = getCurrentResourceStrings(); + expect(Object.keys(resources).length).equals(1); + expect(resources.action_strip_button_more_title).equals('More'); + }); + }); + + describe('base', () => { + it('should correctly detect lang attribute set', async () => { + document.documentElement.setAttribute('lang', 'bg'); + await wait(); + + expect(manager.currentLocale).toEqual('bg'); + // Cleanup dom, since its the same for all tests + document.documentElement.removeAttribute('lang'); + }); + + it('should change current locale correctly', () => { + expect(manager.currentLocale).equal('en-US'); + + manager.setCurrentI18n('bg'); + expect(manager.currentLocale).equal('bg'); + }); + + it('should register new resource string to default locale', () => { + manager.registerI18n(ActionStripResourceStringsEN, manager.defaultLocale); + + const resources = manager.getCurrentResourceStrings(); + expect(manager.currentLocale).equals('en-US'); + expect(Object.keys(resources).length).equals(1); + expect(resources.action_strip_button_more_title).equals('More'); + }); + + it('should override old resource string to currentLocale locale', () => { + manager.registerI18n(ActionStripResourceStringsEN, manager.currentLocale); + manager.registerI18n(ActionStripResourceStringsBG, manager.currentLocale); + + const resources = manager.getCurrentResourceStrings(); + expect(manager.currentLocale).equal('en-US'); + expect(Object.keys(resources).length).equal(1); + expect(resources.action_strip_button_more_title).equal('Още'); + }); + + it('should return empty when registering for changed current locale and default locale is not defined', () => { + manager.setCurrentI18n('bg'); + manager.registerI18n(ActionStripResourceStringsEN, manager.currentLocale); + + let resources = manager.getCurrentResourceStrings(); + expect(manager.currentLocale).equal('bg'); + expect(Object.keys(resources).length).equal(1); + expect(resources.action_strip_button_more_title).equal('More'); + + manager.setCurrentI18n('en-US'); + resources = manager.getCurrentResourceStrings(); + expect(manager.currentLocale).equal('en-US'); + expect(Object.keys(resources).length).equal(0); + }); + + it('should return correct resource when registering for specified locale provided and the current locale is changed to it', () => { + manager.registerI18n(ActionStripResourceStringsBG, 'bg'); + + let resources = manager.getCurrentResourceStrings(); + expect(manager.currentLocale).equal('en-US'); + expect(Object.keys(resources).length).equal(0); + + manager.setCurrentI18n('bg'); + resources = manager.getCurrentResourceStrings(); + expect(Object.keys(resources).length).equal(1); + expect(resources.action_strip_button_more_title).equal('Още'); + }); + + it('should return default resource if current one are not available', () => { + manager.registerI18n(ActionStripResourceStringsEN, manager.defaultLocale); + manager.setCurrentI18n('bg'); + + let resources = manager.getCurrentResourceStrings(); + expect(Object.keys(resources).length).equal(1); + expect(resources.action_strip_button_more_title).equal('More'); + + manager.registerI18n(ActionStripResourceStringsBG, 'bg'); + resources = manager.getCurrentResourceStrings(); + expect(Object.keys(resources).length).equal(1); + expect(resources.action_strip_button_more_title).equal('Още'); + }); + + it('should return same resources for same language but with different locale', () => { + manager.registerI18n(ActionStripResourceStringsES, 'es-ES'); + + manager.setCurrentI18n('es-AR'); + let resources = manager.getCurrentResourceStrings(); + expect(Object.keys(resources).length).equal(1); + expect(resources.action_strip_button_more_title).equal('Más'); + + manager.setCurrentI18n('es-ES'); + resources = manager.getCurrentResourceStrings(); + expect(Object.keys(resources).length).equal(1); + expect(resources.action_strip_button_more_title).equal('Más'); + + manager.setCurrentI18n('es'); + resources = manager.getCurrentResourceStrings(); + expect(Object.keys(resources).length).equal(1); + expect(resources.action_strip_button_more_title).equal('Más'); + }); + }); + + describe('onResourceChange', () => { + let onResourceChangeEvent: { + numTriggered: number; + args: IResourceChangeEventArgs[]; + }; + beforeEach(() => { + onResourceChangeEvent = { + numTriggered: 0, + args: [] + }; + manager.addEventListener('onResourceChange', (args: CustomEvent) => { + onResourceChangeEvent.numTriggered++; + onResourceChangeEvent.args.unshift(args.detail); + }); + }); + + it('should trigger onResourceChange when current locale is changed', () => { + manager.setCurrentI18n('bg'); + manager.setCurrentI18n('en-US'); + + expect(onResourceChangeEvent.numTriggered).equal(2); + expect(onResourceChangeEvent.args[0].oldLocale).equal('bg'); + expect(onResourceChangeEvent.args[0].newLocale).equal('en-US'); + }); + + it('should not trigger onResourceChange when current locale is changed to the same value', () => { + manager.setCurrentI18n('en-US'); + + expect(onResourceChangeEvent.numTriggered).equal(0); + }); + + it('should trigger onResourceChange when new resource strings are registered for the current locale', () => { + manager.registerI18n(ActionStripResourceStringsEN, manager.currentLocale); + expect(onResourceChangeEvent.numTriggered).equal(1); + expect(onResourceChangeEvent.args[0].oldLocale).equal('en-US'); + expect(onResourceChangeEvent.args[0].newLocale).equal('en-US'); + }); + + it('should not trigger onResourceChange when new resource strings are registered for the current locale, but all strings are the same', () => { + manager.registerI18n(ActionStripResourceStringsEN, manager.currentLocale); + manager.registerI18n(ActionStripResourceStringsEN, manager.currentLocale); + + expect(onResourceChangeEvent.numTriggered).equal(1); + expect(onResourceChangeEvent.args[0].oldLocale).equal('en-US'); + expect(onResourceChangeEvent.args[0].newLocale).equal('en-US'); + }); + + it('shouldn not trigger onResourceChange when new resource strings are registered for different locale', () => { + manager.registerI18n(ActionStripResourceStringsEN, 'bg'); + + expect(onResourceChangeEvent.numTriggered).equal(0); + }); + }); +}); diff --git a/projects/igniteui-i18n-core/src/i18n-manager.ts b/projects/igniteui-i18n-core/src/i18n-manager.ts new file mode 100644 index 0000000..35741db --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n-manager.ts @@ -0,0 +1,206 @@ +import type { BaseFormatter } from './formatters/base.formatter.js'; +import { DateFormatter } from './formatters/date.formatter.js'; +import { DisplayNamesFormatter } from './formatters/display-names.formatter.js'; +import { LocaleFormatter } from './formatters/locale.formatter.js'; +import { NumberFormatter } from './formatters/number.formatter.js'; +import type { IResourceStrings } from './i18n/interfaces/resources.interface.js'; +import { + type CustomEventListenerObject, + Formatter, + type I18nManagerEventMap, + I18nManagerEventTarget, + type IIgI18nManager, + type IResourceChangeEventArgs +} from './i18n-manager.interfaces.js'; +import { isBrowser } from './utils.js'; + +const defaultLang = 'en'; +const defaultLocale = 'en-US'; + +export class I18nManager extends I18nManagerEventTarget implements IIgI18nManager { + public defaultLang = defaultLang; + public defaultLocale = defaultLocale; + public currentLocale = defaultLocale; + + private static _instance: I18nManager; + private _formatters = new Map>(); + private _resourcesMap = new Map([[defaultLang, {}]]); + private _rootObserver: MutationObserver | undefined; + + public get localeFormatter(): LocaleFormatter { + return this._formatters.get(Formatter.Locale) as LocaleFormatter; + } + + public get dateFormatter(): DateFormatter { + return this._formatters.get(Formatter.Date) as DateFormatter; + } + + public get numberFormatter(): NumberFormatter { + return this._formatters.get(Formatter.Number) as NumberFormatter; + } + + public get displayNamesFormatter(): DisplayNamesFormatter { + return this._formatters.get(Formatter.DisplayNames) as DisplayNamesFormatter; + } + + public static get instance() { + if (!I18nManager._instance) { + I18nManager._instance = new I18nManager(); + } + return I18nManager._instance; + } + + private constructor() { + super(); + this._formatters.set(Formatter.Locale, new LocaleFormatter(this.defaultLocale)); + this._formatters.set(Formatter.Date, new DateFormatter(this.defaultLocale, this.localeFormatter)); + this._formatters.set(Formatter.Number, new NumberFormatter(this.defaultLocale)); + this._formatters.set(Formatter.DisplayNames, new DisplayNamesFormatter(this.defaultLocale, this.dateFormatter)); + + if (isBrowser()) { + const initialLocale = document.documentElement.getAttribute('lang') ?? this.defaultLocale; + this.setCurrentI18n(initialLocale); + + if (typeof MutationObserver !== 'undefined') { + this._rootObserver = new MutationObserver((mutations: MutationRecord[], observer: MutationObserver) => + this.htmlElementObserve(mutations, observer) + ); + this._rootObserver.observe(document.documentElement, { + attributeFilter: ['lang'] + }); + } + } + } + + /** + * Sets up a function that will be called whenever the specified event is delivered to the target. + * Currently supported events: onResourceChange + * Note: Make sure to bind to events only in browser environment or emulated one. Anything else like server environment does not need to have events. + * @param type Name of the event + * @param listener The function to be called when event is triggered. + * @param options + */ + public override addEventListener( + type: K, + listener: ((evt: I18nManagerEventMap[K]) => void) | CustomEventListenerObject, + options?: boolean | EventListenerOptions + ): void { + if (isBrowser()) { + super.addEventListener(type, listener, options); + } + } + + /** + * Register resource for a locale. Can be the current locale as well or a new one. Results are merged. + */ + public registerI18n(resources: IResourceStrings, locale: string) { + // Use locales language when saving, to make sure for different locales with same language we return same resource strings. + const localeLang = this.localeFormatter.getIntlFormatter(locale).language; + const presentResources = this._resourcesMap.get(localeLang); + let bResourcesChanged = true; + if (presentResources) { + bResourcesChanged = Object.keys(resources).some( + (key) => resources[key as keyof IResourceStrings] !== presentResources[key as keyof IResourceStrings] + ); + const mergedResources = Object.assign(presentResources, resources); + this._resourcesMap.set(localeLang, mergedResources); + } else { + this._resourcesMap.set(localeLang, resources); + } + const currentLocaleLang = this.localeFormatter.getIntlFormatter(this.currentLocale).language; + if (bResourcesChanged && currentLocaleLang === localeLang) { + this.triggerResourceChange(this.currentLocale, this.currentLocale); + } + } + + /** + * Set current locale across all components. + */ + public setCurrentI18n(locale: string) { + const newLocale = Intl.getCanonicalLocales(locale)[0]; + if (this.currentLocale !== newLocale) { + const oldLocale = this.currentLocale; + this.currentLocale = newLocale; + this.triggerResourceChange(oldLocale, newLocale); + + // Update formatters with latest locale. + for (const [_, formatter] of this._formatters) { + formatter.onLocaleChange(newLocale); + } + } + } + + /** + * Get the current resource string for all components in a single object. + */ + public getCurrentResourceStrings(locale?: string) { + const lang = this.localeFormatter.getIntlFormatter(locale ?? this.currentLocale).language; + const currentResources = this._resourcesMap.get(lang); + if (currentResources) { + return currentResources; + } + return this._resourcesMap.get(this.defaultLang) ?? ({} as IResourceStrings); + } + + private triggerResourceChange(oldLocale: string, newLocale: string) { + const eventArgs = { + oldLocale, + newLocale + } as IResourceChangeEventArgs; + if (isBrowser()) { + this.dispatchEvent(new CustomEvent('onResourceChange', { detail: eventArgs })); + } + } + + private htmlElementObserve(mutations: MutationRecord[], _: MutationObserver) { + if (mutations.length && mutations[0].attributeName === 'lang') { + const newLocale = (mutations[0].target as Element).getAttribute('lang') ?? this.currentLocale; + this.setCurrentI18n(newLocale); + } + } +} + +/** + * Gets in the i18nManager instance. + * @internal + */ +export function getI18nManager() { + return I18nManager.instance; +} + +export function getDateFormatter() { + return getI18nManager().dateFormatter; +} + +export function getNumberFormatter() { + return getI18nManager().numberFormatter; +} + +export function getDisplayNamesFormatter() { + return getI18nManager().displayNamesFormatter; +} + +/** + * Register resources for a specific locale. + * @param resourceStrings Object containing the translated resource strings. + * @param locale The name of the locale. A string using the BCP 47 language tag. + */ +export function registerI18n(resourceStrings: IResourceStrings, locale: string) { + getI18nManager().registerI18n(resourceStrings, locale); +} + +/** + * Set the current locale of all IgniteUI components. + * @param locale The name of the locale. A string using the BCP 47 language tag. + */ +export function setCurrentI18n(locale: string) { + getI18nManager().setCurrentI18n(locale); +} + +export function getCurrentI18n() { + return getI18nManager().currentLocale; +} + +export function getCurrentResourceStrings() { + return getI18nManager().getCurrentResourceStrings(); +} diff --git a/projects/igniteui-i18n-core/src/i18n/EN/action-strip-resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/action-strip-resources.ts new file mode 100644 index 0000000..67524f5 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/action-strip-resources.ts @@ -0,0 +1,5 @@ +import type { IActionStripResourceStrings } from '../interfaces/action-strip.interface.js'; + +export const ActionStripResourceStringsEN: IActionStripResourceStrings = { + action_strip_button_more_title: 'More' +} satisfies Required; diff --git a/projects/igniteui-i18n-core/src/i18n/EN/banner-resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/banner-resources.ts new file mode 100644 index 0000000..3e36944 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/banner-resources.ts @@ -0,0 +1,5 @@ +import type { IBannerResourceStrings } from '../interfaces/banner.interface.js'; + +export const BannerResourceStringsEN: IBannerResourceStrings = { + banner_button_dismiss: 'Dismiss' +} satisfies Required; diff --git a/projects/igniteui-i18n-core/src/i18n/EN/calendar-resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/calendar-resources.ts new file mode 100644 index 0000000..d999d19 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/calendar-resources.ts @@ -0,0 +1,26 @@ +import type { ICalendarResourceStrings } from '../interfaces/calendar.interface.js'; + +export const CalendarResourceStringsEN: ICalendarResourceStrings = { + calendar_previous_month: 'Previous Month', + calendar_next_month: 'Next Month', + calendar_previous_year: 'Previous Year', + calendar_next_year: 'Next Year', + calendar_previous_years: 'Previous {0} Years', + calendar_next_years: 'Next {0} Years', + calendar_select_date: 'Select Date', + calendar_select_month: 'Select Month', + calendar_select_year: 'Select Year', + calendar_range_start: 'Range start', + calendar_range_end: 'Range end', + calendar_range_label_start: 'Start', + calendar_range_label_end: 'End', + calendar_range_placeholder: 'Select Range', + calendar_selected_month_is: 'Selected month is ', + calendar_first_picker_of: 'First picker of {0} starts from', + calendar_multi_selection: 'Multi selection calendar with {0} date pickers', + calendar_range_selection: 'Range selection calendar with {0} date pickers', + calendar_single_selection: 'Calendar with {0} date pickers', + calendar_singular_multi_selection: 'Multi selection calendar', + calendar_singular_range_selection: 'Range selection calendar', + calendar_singular_single_selection: 'Calendar' +} satisfies Required; diff --git a/projects/igniteui-i18n-core/src/i18n/EN/carousel-resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/carousel-resources.ts new file mode 100644 index 0000000..e972a81 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/carousel-resources.ts @@ -0,0 +1,8 @@ +import type { ICarouselResourceStrings } from '../interfaces/carousel.interface.js'; + +export const CarouselResourceStringsEN: ICarouselResourceStrings = { + carousel_of: 'of', + carousel_slide: 'slide', + carousel_previous_slide: 'previous slide', + carousel_next_slide: 'next slide' +} satisfies Required; diff --git a/projects/igniteui-i18n-core/src/i18n/EN/chip-resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/chip-resources.ts new file mode 100644 index 0000000..5385938 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/chip-resources.ts @@ -0,0 +1,6 @@ +import type { IChipResourceStrings } from '../interfaces/chip.interface.js'; + +export const ChipResourceStringsEN: IChipResourceStrings = { + chip_remove: 'remove chip', + chip_select: 'select chip' +} satisfies Required; diff --git a/projects/igniteui-i18n-core/src/i18n/EN/combo-resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/combo-resources.ts new file mode 100644 index 0000000..638ead2 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/combo-resources.ts @@ -0,0 +1,10 @@ +import type { IComboResourceStrings } from '../interfaces/combo.interface.js'; + +export const ComboResourceStringsEN: IComboResourceStrings = { + combo_empty_message: 'The list is empty', + combo_filter_search_placeholder: 'Enter a Search Term', + combo_addCustomValues_placeholder: 'Add Item', + combo_clearItems_placeholder: 'Clear Selection', + combo_aria_label_options: 'Selected options', + combo_aria_label_no_options: 'No options selected' +} satisfies Required; diff --git a/projects/igniteui-i18n-core/src/i18n/EN/date-picker-resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/date-picker-resources.ts new file mode 100644 index 0000000..f9e32b0 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/date-picker-resources.ts @@ -0,0 +1,6 @@ +import type { IDatePickerResourceStrings } from '../interfaces/date-picker.interface.js'; + +export const DatePickerResourceStringsEN: IDatePickerResourceStrings = { + date_picker_change_date: 'Change Date', + date_picker_choose_date: 'Choose Date' +} satisfies Required; diff --git a/projects/igniteui-i18n-core/src/i18n/EN/date-range-picker-resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/date-range-picker-resources.ts new file mode 100644 index 0000000..403f1f8 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/date-range-picker-resources.ts @@ -0,0 +1,11 @@ +import type { IDateRangePickerResourceStrings } from '../interfaces/date-range-picker.interface.js'; + +export const DateRangePickerResourceStringsEN: IDateRangePickerResourceStrings = { + date_range_picker_date_separator: 'to', + date_range_picker_done_button: 'Done', + date_range_picker_cancel_button: 'Cancel', + date_range_picker_last7Days: 'Last 7 Days', + date_range_picker_currentMonth: 'Current Month', + date_range_picker_last30Days: 'Last 30 Days', + date_range_picker_yearToDate: 'Year to Date' +} satisfies Required; diff --git a/projects/igniteui-i18n-core/src/i18n/EN/grid-resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/grid-resources.ts new file mode 100644 index 0000000..081a7c2 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/grid-resources.ts @@ -0,0 +1,182 @@ +import { extendResources, GRID_PREFIX, prefixResource } from '../../utils.js'; +import type { GridValidationResourceStrings, IGridResourceStrings } from '../interfaces/grid.interface.js'; +import { ValidationResourceStringsEN } from './validation-resources.js'; + +export const GridResourceStringsEN: IGridResourceStrings = extendResources( + { + grid_groupByArea_message: 'Drag a column header and drop it here to group by that column.', + grid_groupByArea_select_message: 'Select all rows in the group with field name {0} and value {1}.', + grid_groupByArea_deselect_message: 'Deselect all rows in the group with field name {0} and value {1}.', + grid_emptyFilteredGrid_message: 'No records found.', + grid_emptyGrid_message: 'Grid has no data.', + grid_filter: 'Filter', + grid_filter_row_close: 'Close', + grid_filter_row_reset: 'Reset', + grid_filter_row_placeholder: 'Add filter value', + grid_filter_row_boolean_placeholder: 'All', + grid_filter_row_date_placeholder: 'Pick up date', + grid_filter_row_time_placeholder: 'Pick up time', + grid_filter_operator_and: 'And', + grid_filter_operator_or: 'Or', + grid_complex_filter: 'Complex Filter', + grid_filter_contains: 'Contains', + grid_filter_doesNotContain: 'Does Not Contain', + grid_filter_startsWith: 'Starts With', + grid_filter_endsWith: 'Ends With', + grid_filter_equals: 'Equals', + grid_filter_doesNotEqual: 'Does Not Equal', + grid_filter_empty: 'Empty', + grid_filter_notEmpty: 'Not Empty', + grid_filter_null: 'Null', + grid_filter_notNull: 'Not Null', + grid_filter_before: 'Before', + grid_filter_after: 'After', + grid_filter_at: 'At', + grid_filter_not_at: 'Not At', + grid_filter_at_before: 'At or Before', + grid_filter_at_after: 'At or After', + grid_filter_today: 'Today', + grid_filter_yesterday: 'Yesterday', + grid_filter_thisMonth: 'This Month', + grid_filter_lastMonth: 'Last Month', + grid_filter_nextMonth: 'Next Month', + grid_filter_thisYear: 'This Year', + grid_filter_lastYear: 'Last Year', + grid_filter_nextYear: 'Next Year', + grid_filter_greaterThan: 'Greater Than', + grid_filter_lessThan: 'Less Than', + grid_filter_greaterThanOrEqualTo: 'Greater Than Or Equal To', + grid_filter_lessThanOrEqualTo: 'Less Than Or Equal To', + grid_filter_true: 'True', + grid_filter_false: 'False', + grid_filter_all: 'All', + grid_filter_condition_placeholder: 'Select filter', + grid_filter_in: 'In', + grid_filter_notIn: 'Not In', + grid_summary_count: 'Count', + grid_summary_min: 'Min', + grid_summary_max: 'Max', + grid_summary_sum: 'Sum', + grid_summary_average: 'Avg', + grid_summary_earliest: 'Earliest', + grid_summary_latest: 'Latest', + grid_excel_filter_moving_left: 'move left', + grid_excel_filter_moving_left_short: 'left', + grid_excel_filter_moving_right: 'move right', + grid_excel_filter_moving_right_short: 'right', + grid_excel_filter_moving_header: 'move', + grid_excel_filter_sorting_asc: 'ascending', + grid_excel_filter_sorting_asc_short: 'asc', + grid_excel_filter_sorting_desc: 'descending', + grid_excel_filter_sorting_desc_short: 'desc', + grid_excel_filter_sorting_header: 'sort', + grid_excel_filter_clear: 'Clear column filters', + grid_excel_custom_dialog_add: 'add filter', + grid_excel_custom_dialog_clear: 'Clear filter', + grid_excel_custom_dialog_header: 'Custom auto-filter on column: ', + grid_excel_cancel: 'Cancel', + grid_excel_apply: 'Apply', + grid_excel_search_placeholder: 'Search', + grid_excel_select_all: 'Select All', + grid_excel_select_all_search_results: 'Select all search results', + grid_excel_add_to_filter: 'Add current selection to filter', + grid_excel_blanks: '(Blanks)', + grid_excel_hide: 'Hide column', + grid_excel_show: 'Show column', + grid_excel_pin: 'Pin column', + grid_excel_unpin: 'Unpin column', + grid_excel_select: 'Select column', + grid_excel_deselect: 'Deselect column', + grid_excel_text_filter: 'Text filter', + grid_excel_number_filter: 'Number filter', + grid_excel_date_filter: 'Date filter', + grid_excel_boolean_filter: 'Boolean filter', + grid_excel_currency_filter: 'Currency filter', + grid_excel_custom_filter: 'Custom filter...', + grid_excel_no_matches: 'No matches', + grid_excel_matches_count: '{0} matches.', + grid_advanced_filter_title: 'Advanced Filtering', + grid_advanced_filter_from_label: 'From', + grid_advanced_filter_and_group: '"And" Group', + grid_advanced_filter_or_group: '"Or" Group', + grid_advanced_filter_end_group: 'End Group', + grid_advanced_filter_create_and_group: 'Create "And" Group', + grid_advanced_filter_create_or_group: 'Create "Or" Group', + grid_advanced_filter_and_label: 'and', + grid_advanced_filter_or_label: 'or', + grid_advanced_filter_switch_group: 'Switch to {0}', + grid_advanced_filter_add_condition: 'Add condition', + grid_advanced_filter_add_group: 'Add group', + grid_advanced_filter_add_condition_root: 'Condition', + grid_advanced_filter_add_group_root: 'Group', + grid_advanced_filter_ungroup: 'Ungroup', + grid_advanced_filter_delete: 'Delete', + grid_advanced_filter_delete_filters: 'Delete filters', + grid_advanced_filter_initial_text: 'Start with creating a group of conditions linked with "And" or "Or"', + grid_advanced_filter_column_placeholder: 'Select column', + grid_advanced_filter_value_placeholder: 'Value', + grid_advanced_filter_query_value_placeholder: 'Sub-query results', + grid_advanced_filter_select_entity: 'Select entity', + grid_advanced_filter_select_return_field_single: 'Select return field', + grid_advanced_filter_dialog_title: 'Confirmation', + grid_advanced_filter_dialog_message: + 'By changing the entity, you will lose your current settings. Are you sure you want to do that?', + grid_advanced_filter_dialog_checkbox_text: 'Do not show this dialog again', + grid_advanced_filter_drop_ghost_text: 'Drop here to insert', + grid_pinned_row_indicator: 'Pinned', + grid_hiding_check_all_label: 'Show All', + grid_hiding_uncheck_all_label: 'Hide All', + grid_pinning_check_all_label: 'Pin All', + grid_pinning_uncheck_all_label: 'Unpin All', + grid_row_edit_btn_done: 'Done', + grid_row_edit_btn_cancel: 'Cancel', + grid_row_edit_text: 'You have {0} changes in this row and {1} hidden columns', + grid_toolbar_actions_filter_prompt: 'Filter columns list ...', + grid_toolbar_pinning_button_tooltip: 'Open column pinning dropdown', + grid_toolbar_hiding_button_tooltip: 'Open column hiding dropdown', + grid_toolbar_pinning_title: 'Pinned columns', + grid_toolbar_hiding_title: 'Visible columns', + grid_toolbar_advanced_filtering_button_tooltip: 'Open advanced filtering dialog', + grid_toolbar_advanced_filtering_button_label: 'Advanced filtering', + grid_toolbar_exporter_button_tooltip: 'Open exporter dropdown', + grid_toolbar_exporter_button_label: 'Export', + grid_toolbar_exporter_excel_entry_text: 'Export to Excel', + grid_toolbar_exporter_csv_entry_text: 'Export to CSV', + grid_snackbar_addrow_label: 'Row added', + grid_snackbar_addrow_actiontext: 'SHOW', + grid_actions_edit_label: 'Edit', + grid_actions_add_label: 'Add', + grid_add_row_label: 'ADD ROW', + grid_actions_add_child_label: 'Add Child', + grid_actions_delete_label: 'Delete', + grid_actions_pin_label: 'Pin', + grid_actions_unpin_label: 'Unpin', + grid_actions_jumpUp_label: 'Jump up', + grid_actions_jumpDown_label: 'Jump down', + grid_pivot_date_dimension_total: 'All Periods', + grid_pivot_aggregate_count: 'Count', + grid_pivot_aggregate_min: 'Minimum', + grid_pivot_aggregate_max: 'Maximum', + grid_pivot_aggregate_sum: 'Sum', + grid_pivot_aggregate_avg: 'Average', + grid_pivot_aggregate_date_latest: 'Latest Date', + grid_pivot_aggregate_date_earliest: 'Earliest Date', + grid_pivot_aggregate_time_latest: 'Latest Time', + grid_pivot_aggregate_time_earliest: 'Earliest Time', + grid_pivot_empty_row_drop_area: 'Drop Row Fields here.', + grid_pivot_empty_column_drop_area: 'Drop Column Fields here.', + grid_pivot_empty_filter_drop_area: 'Drop Filter Fields here.', + grid_pivot_empty_value_drop_area: 'Drop Value Fields here.', + grid_pivot_row_drop_chip: 'Drop here to use as row', + grid_pivot_column_drop_chip: 'Drop here to use as column', + grid_pivot_filter_drop_chip: 'Drop here to use as filter', + grid_pivot_value_drop_chip: 'Drop here to use as value', + grid_pivot_empty_message: 'Pivot grid has no dimensions and values.', + grid_pivot_selector_filters: 'Filters', + grid_pivot_selector_rows: 'Rows', + grid_pivot_selector_columns: 'Columns', + grid_pivot_selector_values: 'Values', + grid_pivot_selector_panel_empty: 'Drop Items Here' + } satisfies Required>, + prefixResource(GRID_PREFIX, ValidationResourceStringsEN) +); diff --git a/projects/igniteui-i18n-core/src/i18n/EN/index.ts b/projects/igniteui-i18n-core/src/i18n/EN/index.ts new file mode 100644 index 0000000..e4c1ddc --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/index.ts @@ -0,0 +1,17 @@ +export * from './action-strip-resources.js'; +export * from './banner-resources.js'; +export * from './calendar-resources.js'; +export * from './carousel-resources.js'; +export * from './chip-resources.js'; +export * from './combo-resources.js'; +export * from './date-picker-resources.js'; +export * from './date-range-picker-resources.js'; +export * from './grid-resources.js'; +export * from './input-resources.js'; +export * from './list-resources.js'; +export * from './paginator-resources.js'; +export * from './query-builder-resources.js'; +export * from './resources.js'; +export * from './time-picker-resources.js'; +export * from './tree-resources.js'; +export * from './validation-resources.js'; diff --git a/projects/igniteui-i18n-core/src/i18n/EN/input-resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/input-resources.ts new file mode 100644 index 0000000..d8636e9 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/input-resources.ts @@ -0,0 +1,6 @@ +import type { IInputResourceStrings } from '../interfaces/input.interface.js'; + +export const InputResourceStringsEN: IInputResourceStrings = { + input_upload_button: 'Browse', + input_file_placeholder: 'No file chosen' +} satisfies Required; diff --git a/projects/igniteui-i18n-core/src/i18n/EN/list-resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/list-resources.ts new file mode 100644 index 0000000..7a55045 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/list-resources.ts @@ -0,0 +1,6 @@ +import type { IListResourceStrings } from '../interfaces/list.interface.js'; + +export const ListResourceStringsEN: IListResourceStrings = { + list_no_items: 'There are no items in the list.', + list_loading: 'Loading data from the server...' +} satisfies Required; diff --git a/projects/igniteui-i18n-core/src/i18n/EN/paginator-resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/paginator-resources.ts new file mode 100644 index 0000000..f69c683 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/paginator-resources.ts @@ -0,0 +1,10 @@ +import type { IPaginatorResourceStrings } from '../interfaces/paginator.interface.js'; + +export const PaginatorResourceStringsEN: IPaginatorResourceStrings = { + paginator_label: 'Items per page', + paginator_pager_text: 'of', + paginator_first_page_button_text: 'Go to first page', + paginator_previous_page_button_text: 'Previous page', + paginator_last_page_button_text: 'Go to last page', + paginator_next_page_button_text: 'Next page' +} satisfies Required; diff --git a/projects/igniteui-i18n-core/src/i18n/EN/query-builder-resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/query-builder-resources.ts new file mode 100644 index 0000000..92959aa --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/query-builder-resources.ts @@ -0,0 +1,77 @@ +import type { IQueryBuilderResourceStrings } from '../interfaces/query-builder.interface.js'; + +export const QueryBuilderResourceStringsEN: IQueryBuilderResourceStrings = { + query_builder_date_placeholder: 'Select date', + query_builder_time_placeholder: 'Select time', + query_builder_datetime_placeholder: 'Select date & time', + query_builder_filter_operator_and: 'And', + query_builder_filter_operator_or: 'Or', + query_builder_filter_contains: 'Contains', + query_builder_filter_doesNotContain: 'Does Not Contain', + query_builder_filter_startsWith: 'Starts With', + query_builder_filter_endsWith: 'Ends With', + query_builder_filter_equals: 'Equals', + query_builder_filter_doesNotEqual: 'Does Not Equal', + query_builder_filter_empty: 'Empty', + query_builder_filter_notEmpty: 'Not Empty', + query_builder_filter_null: 'Null', + query_builder_filter_notNull: 'Not Null', + query_builder_filter_in: 'In', + query_builder_filter_notIn: 'Not In', + query_builder_filter_before: 'Before', + query_builder_filter_after: 'After', + query_builder_filter_at: 'At', + query_builder_filter_not_at: 'Not At', + query_builder_filter_at_before: 'At or Before', + query_builder_filter_at_after: 'At or After', + query_builder_filter_today: 'Today', + query_builder_filter_yesterday: 'Yesterday', + query_builder_filter_thisMonth: 'This Month', + query_builder_filter_lastMonth: 'Last Month', + query_builder_filter_nextMonth: 'Next Month', + query_builder_filter_thisYear: 'This Year', + query_builder_filter_lastYear: 'Last Year', + query_builder_filter_nextYear: 'Next Year', + query_builder_filter_greaterThan: 'Greater Than', + query_builder_filter_lessThan: 'Less Than', + query_builder_filter_greaterThanOrEqualTo: 'Greater Than Or Equal To', + query_builder_filter_lessThanOrEqualTo: 'Less Than Or Equal To', + query_builder_filter_true: 'True', + query_builder_filter_false: 'False', + query_builder_filter_all: 'All', + query_builder_from_label: 'From', + query_builder_select_label: 'Select', + query_builder_where_label: 'Where', + query_builder_and_group: '"And" Group', + query_builder_or_group: '"Or" Group', + query_builder_end_group: 'End Group', + query_builder_and_label: 'and', + query_builder_or_label: 'or', + query_builder_switch_group: 'Switch to {0}', + query_builder_add_condition: 'Add condition', + query_builder_add_group: 'Add group', + query_builder_add_condition_root: 'Condition', + query_builder_add_group_root: 'Group', + query_builder_ungroup: 'Ungroup', + query_builder_delete: 'Delete', + query_builder_delete_filters: 'Delete filters', + query_builder_initial_text: 'Start with creating a group of conditions linked with "And" or "Or"', + query_builder_column_placeholder: 'Select column', + query_builder_condition_placeholder: 'Select filter', + query_builder_value_placeholder: 'Value', + query_builder_query_value_placeholder: 'Sub-query results', + query_builder_all_fields: 'All fields', + query_builder_details: 'Details', + query_builder_search: 'Search', + query_builder_select_all: 'Select All', + query_builder_select_entity: 'Select entity', + query_builder_select_return_field_single: 'Select return field', + query_builder_select_return_fields: 'Select return fields', + query_builder_dialog_title: 'Confirmation', + query_builder_dialog_message: + 'By changing the entity, you will lose your current settings. Are you sure you want to do that?', + query_builder_dialog_checkbox_text: 'Do not show this dialog again', + query_builder_dialog_cancel: 'Cancel', + query_builder_dialog_confirm: 'Confirm', + query_builder_drop_ghost_text: 'Drop here to insert' +} satisfies Required; diff --git a/projects/igniteui-i18n-core/src/i18n/EN/resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/resources.ts new file mode 100644 index 0000000..509c2b6 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/resources.ts @@ -0,0 +1,39 @@ +import type { IResourceStrings } from '../interfaces/resources.interface.js'; +import { ActionStripResourceStringsEN } from './action-strip-resources.js'; +import { BannerResourceStringsEN } from './banner-resources.js'; +import { CalendarResourceStringsEN } from './calendar-resources.js'; +import { CarouselResourceStringsEN } from './carousel-resources.js'; +import { ChipResourceStringsEN } from './chip-resources.js'; +import { ComboResourceStringsEN } from './combo-resources.js'; +import { DatePickerResourceStringsEN } from './date-picker-resources.js'; +import { DateRangePickerResourceStringsEN } from './date-range-picker-resources.js'; +import { GridResourceStringsEN } from './grid-resources.js'; +import { InputResourceStringsEN } from './input-resources.js'; +import { ListResourceStringsEN } from './list-resources.js'; +import { PaginatorResourceStringsEN } from './paginator-resources.js'; +import { QueryBuilderResourceStringsEN } from './query-builder-resources.js'; +import { TimePickerResourceStringsEN } from './time-picker-resources.js'; +import { TreeResourceStringsEN } from './tree-resources.js'; +import { ValidationResourceStringsEN } from './validation-resources.js'; + +/** + * English resource strings for all components + */ +export const ResourceStringsEN: IResourceStrings = { + ...ActionStripResourceStringsEN, + ...BannerResourceStringsEN, + ...CalendarResourceStringsEN, + ...CarouselResourceStringsEN, + ...ChipResourceStringsEN, + ...ComboResourceStringsEN, + ...DatePickerResourceStringsEN, + ...DateRangePickerResourceStringsEN, + ...GridResourceStringsEN, + ...InputResourceStringsEN, + ...ListResourceStringsEN, + ...PaginatorResourceStringsEN, + ...QueryBuilderResourceStringsEN, + ...TimePickerResourceStringsEN, + ...TreeResourceStringsEN, + ...ValidationResourceStringsEN +}; diff --git a/projects/igniteui-i18n-core/src/i18n/EN/time-picker-resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/time-picker-resources.ts new file mode 100644 index 0000000..dbcd583 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/time-picker-resources.ts @@ -0,0 +1,8 @@ +import type { ITimePickerResourceStrings } from '../interfaces/time-picker.interface.js'; + +export const TimePickerResourceStringsEN: ITimePickerResourceStrings = { + time_picker_ok: 'OK', + time_picker_cancel: 'Cancel', + time_picker_change_time: 'Change Time', + time_picker_choose_time: 'Choose Time' +} satisfies Required; diff --git a/projects/igniteui-i18n-core/src/i18n/EN/tree-resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/tree-resources.ts new file mode 100644 index 0000000..16fd2b9 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/tree-resources.ts @@ -0,0 +1,6 @@ +import type { ITreeResourceStrings } from '../interfaces/tree.interface.js'; + +export const TreeResourceStringsEN: ITreeResourceStrings = { + expand: 'Expand', + collapse: 'Collapse' +} satisfies Required; diff --git a/projects/igniteui-i18n-core/src/i18n/EN/validation-resources.ts b/projects/igniteui-i18n-core/src/i18n/EN/validation-resources.ts new file mode 100644 index 0000000..ca103a3 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/EN/validation-resources.ts @@ -0,0 +1,14 @@ +import type { IValidationResourceStrings } from '../interfaces/validation.interface.js'; + +export const ValidationResourceStringsEN: IValidationResourceStrings = { + required_validation_error: 'This field is required', + min_validation_error: 'A value of at least {0} should be entered', + max_validation_error: 'A value no more than {0} should be entered', + min_length_validation_error: 'Entry should be at least {0} character(s) long', + max_length_validation_error: 'Entry should be no more than {0} character(s) long', + email_validation_error: 'A valid email address should be entered', + pattern_validation_error: 'Entry does not match the required pattern', + mask_validation_error: 'All required positions should be filled', + url_validation_error: 'A valid url address should be entered', + disabled_date_validation_error: 'The entered value {0} is within the disabled dates range' +} satisfies Required; diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/action-strip.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/action-strip.interface.ts new file mode 100644 index 0000000..21d0362 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/action-strip.interface.ts @@ -0,0 +1,3 @@ +export interface IActionStripResourceStrings { + action_strip_button_more_title?: string; +} diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/banner.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/banner.interface.ts new file mode 100644 index 0000000..29e8fff --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/banner.interface.ts @@ -0,0 +1,3 @@ +export interface IBannerResourceStrings { + banner_button_dismiss?: string; +} diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/calendar.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/calendar.interface.ts new file mode 100644 index 0000000..d5ff80c --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/calendar.interface.ts @@ -0,0 +1,24 @@ +export interface ICalendarResourceStrings { + calendar_previous_month?: string; + calendar_next_month?: string; + calendar_previous_year?: string; + calendar_next_year?: string; + calendar_previous_years?: string; + calendar_next_years?: string; + calendar_select_date?: string; + calendar_select_month?: string; + calendar_select_year?: string; + calendar_range_start?: string; + calendar_range_end?: string; + calendar_range_label_start?: string; + calendar_range_label_end?: string; + calendar_range_placeholder?: string; + calendar_selected_month_is?: string; + calendar_first_picker_of?: string; + calendar_multi_selection?: string; + calendar_range_selection?: string; + calendar_single_selection?: string; + calendar_singular_multi_selection?: string; + calendar_singular_range_selection?: string; + calendar_singular_single_selection?: string; +} diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/carousel.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/carousel.interface.ts new file mode 100644 index 0000000..5c36fbf --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/carousel.interface.ts @@ -0,0 +1,6 @@ +export interface ICarouselResourceStrings { + carousel_of?: string; + carousel_slide?: string; + carousel_previous_slide?: string; + carousel_next_slide?: string; +} diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/chip.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/chip.interface.ts new file mode 100644 index 0000000..3c0230b --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/chip.interface.ts @@ -0,0 +1,4 @@ +export interface IChipResourceStrings { + chip_remove?: string; + chip_select?: string; +} diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/combo.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/combo.interface.ts new file mode 100644 index 0000000..46a361b --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/combo.interface.ts @@ -0,0 +1,8 @@ +export interface IComboResourceStrings { + combo_empty_message?: string; + combo_filter_search_placeholder?: string; + combo_addCustomValues_placeholder?: string; + combo_clearItems_placeholder?: string; + combo_aria_label_options?: string; + combo_aria_label_no_options?: string; +} diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/date-picker.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/date-picker.interface.ts new file mode 100644 index 0000000..dec0644 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/date-picker.interface.ts @@ -0,0 +1,4 @@ +export interface IDatePickerResourceStrings { + date_picker_change_date?: string; + date_picker_choose_date?: string; +} diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/date-range-picker.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/date-range-picker.interface.ts new file mode 100644 index 0000000..e39161b --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/date-range-picker.interface.ts @@ -0,0 +1,9 @@ +export interface IDateRangePickerResourceStrings { + date_range_picker_date_separator?: string; + date_range_picker_done_button?: string; + date_range_picker_cancel_button?: string; + date_range_picker_last7Days?: string; + date_range_picker_currentMonth?: string; + date_range_picker_last30Days?: string; + date_range_picker_yearToDate?: string; +} diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/grid.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/grid.interface.ts new file mode 100644 index 0000000..dfcf51e --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/grid.interface.ts @@ -0,0 +1,180 @@ +import type { PrefixedResourceStrings } from '../../i18n-manager.interfaces.js'; +import type { GRID_PREFIX } from '../../utils.js'; +import type { IValidationResourceStrings } from './validation.interface.js'; + +export type GridValidationResourceStrings = PrefixedResourceStrings; + +export interface IGridResourceStrings extends GridValidationResourceStrings { + grid_groupByArea_message?: string; + grid_groupByArea_select_message?: string; + grid_groupByArea_deselect_message?: string; + grid_emptyFilteredGrid_message?: string; + grid_emptyGrid_message?: string; + grid_filter?: string; + grid_filter_row_close?: string; + grid_filter_row_reset?: string; + grid_filter_row_placeholder?: string; + grid_filter_row_boolean_placeholder?: string; + grid_filter_row_date_placeholder?: string; + grid_filter_row_time_placeholder?: string; + grid_filter_operator_and?: string; + grid_complex_filter?: string; + grid_filter_operator_or?: string; + grid_filter_contains?: string; + grid_filter_doesNotContain?: string; + grid_filter_startsWith?: string; + grid_filter_endsWith?: string; + grid_filter_equals?: string; + grid_filter_doesNotEqual?: string; + grid_filter_empty?: string; + grid_filter_notEmpty?: string; + grid_filter_null?: string; + grid_filter_notNull?: string; + grid_filter_before?: string; + grid_filter_after?: string; + grid_filter_at?: string; + grid_filter_not_at?: string; + grid_filter_at_before?: string; + grid_filter_at_after?: string; + grid_filter_today?: string; + grid_filter_yesterday?: string; + grid_filter_thisMonth?: string; + grid_filter_lastMonth?: string; + grid_filter_nextMonth?: string; + grid_filter_thisYear?: string; + grid_filter_lastYear?: string; + grid_filter_nextYear?: string; + grid_filter_greaterThan?: string; + grid_filter_lessThan?: string; + grid_filter_greaterThanOrEqualTo?: string; + grid_filter_lessThanOrEqualTo?: string; + grid_filter_true?: string; + grid_filter_false?: string; + grid_filter_all?: string; + grid_filter_in?: string; + grid_filter_notIn?: string; + grid_filter_condition_placeholder?: string; + grid_summary_count?: string; + grid_summary_min?: string; + grid_summary_max?: string; + grid_summary_sum?: string; + grid_summary_average?: string; + grid_summary_earliest?: string; + grid_summary_latest?: string; + grid_excel_filter_moving_left?: string; + grid_excel_filter_moving_left_short?: string; + grid_excel_filter_moving_right?: string; + grid_excel_filter_moving_right_short?: string; + grid_excel_filter_moving_header?: string; + grid_excel_filter_sorting_asc?: string; + grid_excel_filter_sorting_asc_short?: string; + grid_excel_filter_sorting_desc?: string; + grid_excel_filter_sorting_desc_short?: string; + grid_excel_filter_sorting_header?: string; + grid_excel_filter_clear?: string; + grid_excel_custom_dialog_add?: string; + grid_excel_custom_dialog_clear?: string; + grid_excel_custom_dialog_header?: string; + grid_excel_cancel?: string; + grid_excel_apply?: string; + grid_excel_search_placeholder?: string; + grid_excel_select_all?: string; + grid_excel_select_all_search_results?: string; + grid_excel_add_to_filter?: string; + grid_excel_blanks?: string; + grid_excel_hide?: string; + grid_excel_show?: string; + grid_excel_pin?: string; + grid_excel_unpin?: string; + grid_excel_select?: string; + grid_excel_deselect?: string; + grid_excel_text_filter?: string; + grid_excel_number_filter?: string; + grid_excel_date_filter?: string; + grid_excel_boolean_filter?: string; + grid_excel_currency_filter?: string; + grid_excel_custom_filter?: string; + grid_excel_no_matches?: string; + grid_excel_matches_count?: string; + grid_advanced_filter_title?: string; + grid_advanced_filter_from_label?: string; + grid_advanced_filter_and_group?: string; + grid_advanced_filter_or_group?: string; + grid_advanced_filter_end_group?: string; + grid_advanced_filter_create_and_group?: string; + grid_advanced_filter_create_or_group?: string; + grid_advanced_filter_and_label?: string; + grid_advanced_filter_or_label?: string; + grid_advanced_filter_add_condition?: string; + grid_advanced_filter_add_condition_root?: string; + grid_advanced_filter_add_group?: string; + grid_advanced_filter_add_group_root?: string; + grid_advanced_filter_ungroup?: string; + grid_advanced_filter_delete?: string; + grid_advanced_filter_delete_filters?: string; + grid_advanced_filter_initial_text?: string; + grid_advanced_filter_column_placeholder?: string; + grid_advanced_filter_value_placeholder?: string; + grid_advanced_filter_query_value_placeholder?: string; + grid_advanced_filter_switch_group?: string; + grid_advanced_filter_dialog_title?: string; + grid_advanced_filter_dialog_message?: string; + grid_advanced_filter_dialog_checkbox_text?: string; + grid_advanced_filter_drop_ghost_text?: string; + grid_advanced_filter_select_entity?: string; + grid_advanced_filter_select_return_field_single?: string; + grid_pinned_row_indicator?: string; + grid_hiding_check_all_label?: string; + grid_hiding_uncheck_all_label?: string; + grid_pinning_check_all_label?: string; + grid_pinning_uncheck_all_label?: string; + grid_row_edit_btn_done?: string; + grid_row_edit_btn_cancel?: string; + grid_row_edit_text?: string; + grid_toolbar_actions_filter_prompt?: string; + grid_toolbar_pinning_button_tooltip?: string; + grid_toolbar_hiding_button_tooltip?: string; + grid_toolbar_pinning_title?: string; + grid_toolbar_hiding_title?: string; + grid_toolbar_advanced_filtering_button_tooltip?: string; + grid_toolbar_advanced_filtering_button_label?: string; + grid_toolbar_exporter_button_tooltip?: string; + grid_toolbar_exporter_button_label?: string; + grid_toolbar_exporter_excel_entry_text?: string; + grid_toolbar_exporter_csv_entry_text?: string; + grid_snackbar_addrow_label?: string; + grid_snackbar_addrow_actiontext?: string; + grid_actions_edit_label?: string; + grid_actions_add_label?: string; + grid_add_row_label?: string; + grid_actions_add_child_label?: string; + grid_actions_delete_label?: string; + grid_actions_pin_label?: string; + grid_actions_unpin_label?: string; + grid_actions_jumpUp_label?: string; + grid_actions_jumpDown_label?: string; + grid_pivot_date_dimension_total?: string; + grid_pivot_aggregate_count?: string; + grid_pivot_aggregate_min?: string; + grid_pivot_aggregate_max?: string; + grid_pivot_aggregate_sum?: string; + grid_pivot_aggregate_avg?: string; + grid_pivot_aggregate_date_latest?: string; + grid_pivot_aggregate_date_earliest?: string; + grid_pivot_aggregate_time_latest?: string; + grid_pivot_aggregate_time_earliest?: string; + grid_pivot_empty_row_drop_area?: string; + grid_pivot_empty_column_drop_area?: string; + grid_pivot_empty_filter_drop_area?: string; + grid_pivot_empty_value_drop_area?: string; + grid_pivot_row_drop_chip?: string; + grid_pivot_column_drop_chip?: string; + grid_pivot_filter_drop_chip?: string; + grid_pivot_value_drop_chip?: string; + grid_pivot_empty_message?: string; + grid_pivot_selector_filters?: string; + grid_pivot_selector_rows?: string; + grid_pivot_selector_columns?: string; + grid_pivot_selector_values?: string; + grid_pivot_selector_panel_empty?: string; +} diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/input.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/input.interface.ts new file mode 100644 index 0000000..3971c87 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/input.interface.ts @@ -0,0 +1,4 @@ +export interface IInputResourceStrings { + input_upload_button?: string; + input_file_placeholder?: string; +} diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/list.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/list.interface.ts new file mode 100644 index 0000000..191e06b --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/list.interface.ts @@ -0,0 +1,4 @@ +export interface IListResourceStrings { + list_no_items?: string; + list_loading?: string; +} diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/paginator.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/paginator.interface.ts new file mode 100644 index 0000000..2af00a7 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/paginator.interface.ts @@ -0,0 +1,8 @@ +export interface IPaginatorResourceStrings { + paginator_label?: string; + paginator_pager_text?: string; + paginator_first_page_button_text?: string; + paginator_previous_page_button_text?: string; + paginator_last_page_button_text?: string; + paginator_next_page_button_text?: string; +} diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/query-builder.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/query-builder.interface.ts new file mode 100644 index 0000000..5cd7a44 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/query-builder.interface.ts @@ -0,0 +1,74 @@ +export interface IQueryBuilderResourceStrings { + query_builder_date_placeholder?: string; + query_builder_time_placeholder?: string; + query_builder_datetime_placeholder?: string; + query_builder_filter_operator_and?: string; + query_builder_filter_operator_or?: string; + query_builder_filter_contains?: string; + query_builder_filter_doesNotContain?: string; + query_builder_filter_startsWith?: string; + query_builder_filter_endsWith?: string; + query_builder_filter_equals?: string; + query_builder_filter_doesNotEqual?: string; + query_builder_filter_empty?: string; + query_builder_filter_notEmpty?: string; + query_builder_filter_null?: string; + query_builder_filter_notNull?: string; + query_builder_filter_in?: string; + query_builder_filter_notIn?: string; + query_builder_filter_before?: string; + query_builder_filter_after?: string; + query_builder_filter_at?: string; + query_builder_filter_not_at?: string; + query_builder_filter_at_before?: string; + query_builder_filter_at_after?: string; + query_builder_filter_today?: string; + query_builder_filter_yesterday?: string; + query_builder_filter_thisMonth?: string; + query_builder_filter_lastMonth?: string; + query_builder_filter_nextMonth?: string; + query_builder_filter_thisYear?: string; + query_builder_filter_lastYear?: string; + query_builder_filter_nextYear?: string; + query_builder_filter_greaterThan?: string; + query_builder_filter_lessThan?: string; + query_builder_filter_greaterThanOrEqualTo?: string; + query_builder_filter_lessThanOrEqualTo?: string; + query_builder_filter_true?: string; + query_builder_filter_false?: string; + query_builder_filter_all?: string; + query_builder_from_label?: string; + query_builder_select_label?: string; + query_builder_where_label?: string; + query_builder_and_group?: string; + query_builder_or_group?: string; + query_builder_end_group?: string; + query_builder_and_label?: string; + query_builder_or_label?: string; + query_builder_switch_group?: string; + query_builder_add_condition?: string; + query_builder_add_group?: string; + query_builder_add_condition_root?: string; + query_builder_add_group_root?: string; + query_builder_ungroup?: string; + query_builder_delete?: string; + query_builder_delete_filters?: string; + query_builder_initial_text?: string; + query_builder_column_placeholder?: string; + query_builder_condition_placeholder?: string; + query_builder_value_placeholder?: string; + query_builder_query_value_placeholder?: string; + query_builder_all_fields?: string; + query_builder_details?: string; + query_builder_search?: string; + query_builder_select_all?: string; + query_builder_select_entity?: string; + query_builder_select_return_field_single?: string; + query_builder_select_return_fields?: string; + query_builder_dialog_title?: string; + query_builder_dialog_message?: string; + query_builder_dialog_checkbox_text?: string; + query_builder_dialog_cancel?: string; + query_builder_dialog_confirm?: string; + query_builder_drop_ghost_text?: string; +} diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/resources.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/resources.interface.ts new file mode 100644 index 0000000..dfe79be --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/resources.interface.ts @@ -0,0 +1,34 @@ +import type { IActionStripResourceStrings } from './action-strip.interface.js'; +import type { IBannerResourceStrings } from './banner.interface.js'; +import type { ICalendarResourceStrings } from './calendar.interface.js'; +import type { ICarouselResourceStrings } from './carousel.interface.js'; +import type { IChipResourceStrings } from './chip.interface.js'; +import type { IComboResourceStrings } from './combo.interface.js'; +import type { IDatePickerResourceStrings } from './date-picker.interface.js'; +import type { IDateRangePickerResourceStrings } from './date-range-picker.interface.js'; +import type { IGridResourceStrings } from './grid.interface.js'; +import type { IInputResourceStrings } from './input.interface.js'; +import type { IListResourceStrings } from './list.interface.js'; +import type { IPaginatorResourceStrings } from './paginator.interface.js'; +import type { IQueryBuilderResourceStrings } from './query-builder.interface.js'; +import type { ITimePickerResourceStrings } from './time-picker.interface.js'; +import type { ITreeResourceStrings } from './tree.interface.js'; +import type { IValidationResourceStrings } from './validation.interface.js'; + +export interface IResourceStrings + extends IGridResourceStrings, + IActionStripResourceStrings, + IBannerResourceStrings, + ICalendarResourceStrings, + ICarouselResourceStrings, + IChipResourceStrings, + IComboResourceStrings, + IDatePickerResourceStrings, + IDateRangePickerResourceStrings, + IInputResourceStrings, + IListResourceStrings, + IPaginatorResourceStrings, + IQueryBuilderResourceStrings, + ITimePickerResourceStrings, + ITreeResourceStrings, + IValidationResourceStrings {} diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/time-picker.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/time-picker.interface.ts new file mode 100644 index 0000000..bdf3145 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/time-picker.interface.ts @@ -0,0 +1,6 @@ +export interface ITimePickerResourceStrings { + time_picker_ok?: string; + time_picker_cancel?: string; + time_picker_change_time?: string; + time_picker_choose_time?: string; +} diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/tree.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/tree.interface.ts new file mode 100644 index 0000000..dd5af1a --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/tree.interface.ts @@ -0,0 +1,4 @@ +export interface ITreeResourceStrings { + expand?: string; + collapse?: string; +} diff --git a/projects/igniteui-i18n-core/src/i18n/interfaces/validation.interface.ts b/projects/igniteui-i18n-core/src/i18n/interfaces/validation.interface.ts new file mode 100644 index 0000000..2cbf8c9 --- /dev/null +++ b/projects/igniteui-i18n-core/src/i18n/interfaces/validation.interface.ts @@ -0,0 +1,12 @@ +export interface IValidationResourceStrings { + required_validation_error?: string; + min_validation_error?: string; + max_validation_error?: string; + min_length_validation_error?: string; + max_length_validation_error?: string; + email_validation_error?: string; + pattern_validation_error?: string; + mask_validation_error?: string; + url_validation_error?: string; + disabled_date_validation_error?: string; +} diff --git a/projects/igniteui-i18n-core/src/index.ts b/projects/igniteui-i18n-core/src/index.ts new file mode 100644 index 0000000..8e100ee --- /dev/null +++ b/projects/igniteui-i18n-core/src/index.ts @@ -0,0 +1,50 @@ +export * from './i18n/EN/action-strip-resources.js'; +export * from './i18n/EN/banner-resources.js'; +export * from './i18n/EN/calendar-resources.js'; +export * from './i18n/EN/carousel-resources.js'; +export * from './i18n/EN/chip-resources.js'; +export * from './i18n/EN/combo-resources.js'; +export * from './i18n/EN/date-picker-resources.js'; +export * from './i18n/EN/date-range-picker-resources.js'; +export * from './i18n/EN/grid-resources.js'; +export * from './i18n/EN/input-resources.js'; +export * from './i18n/EN/list-resources.js'; +export * from './i18n/EN/paginator-resources.js'; +export * from './i18n/EN/query-builder-resources.js'; +export * from './i18n/EN/resources.js'; +export * from './i18n/EN/time-picker-resources.js'; +export * from './i18n/EN/tree-resources.js'; +export * from './i18n/EN/validation-resources.js'; +export * from './i18n/interfaces/action-strip.interface.js'; +export * from './i18n/interfaces/banner.interface.js'; +export * from './i18n/interfaces/calendar.interface.js'; +export * from './i18n/interfaces/carousel.interface.js'; +export * from './i18n/interfaces/chip.interface.js'; +export * from './i18n/interfaces/combo.interface.js'; +export * from './i18n/interfaces/date-picker.interface.js'; +export * from './i18n/interfaces/date-range-picker.interface.js'; +export * from './i18n/interfaces/grid.interface.js'; +export * from './i18n/interfaces/input.interface.js'; +export * from './i18n/interfaces/list.interface.js'; +export * from './i18n/interfaces/paginator.interface.js'; +export * from './i18n/interfaces/query-builder.interface.js'; +export * from './i18n/interfaces/resources.interface.js'; +export * from './i18n/interfaces/time-picker.interface.js'; +export * from './i18n/interfaces/tree.interface.js'; +export * from './i18n/interfaces/validation.interface.js'; +export type { + ICustomFormatOptions, + IResourceChangeEventArgs, + PrefixedResourceStrings +} from './i18n-manager.interfaces.js'; +export { + getCurrentI18n, + getCurrentResourceStrings, + getDateFormatter, + getDisplayNamesFormatter, + getI18nManager, + getNumberFormatter, + registerI18n, + setCurrentI18n +} from './i18n-manager.js'; +export { extendResources, GRID_PREFIX, IGX_PREFIX, prefixResource } from './utils.js'; diff --git a/projects/igniteui-i18n-core/src/test-utils.ts b/projects/igniteui-i18n-core/src/test-utils.ts new file mode 100644 index 0000000..6b71d6b --- /dev/null +++ b/projects/igniteui-i18n-core/src/test-utils.ts @@ -0,0 +1 @@ +export const wait = (ms = 0) => new Promise((resolve) => setTimeout(resolve, ms)); diff --git a/projects/igniteui-i18n-core/src/utils.spec.ts b/projects/igniteui-i18n-core/src/utils.spec.ts new file mode 100644 index 0000000..2a4e90e --- /dev/null +++ b/projects/igniteui-i18n-core/src/utils.spec.ts @@ -0,0 +1,18 @@ +import { describe, expect, it } from 'vitest'; +import { generateLocaleKey } from './utils.js'; + +describe('util', () => { + it('generateLocaleKey should produce same key for objects with same values, regardless or order of keys', () => { + const optionsA = { + currency: 'BGN', + compactDisplay: 'long' + } as Intl.NumberFormatOptions; + const optionsB = { + compactDisplay: 'long', + currency: 'BGN' + } as Intl.NumberFormatOptions; + const keyA = generateLocaleKey('bg', optionsA); + const keyB = generateLocaleKey('bg', optionsB); + expect(keyA).equal(keyB); + }); +}); diff --git a/projects/igniteui-i18n-core/src/utils.ts b/projects/igniteui-i18n-core/src/utils.ts new file mode 100644 index 0000000..9c454c0 --- /dev/null +++ b/projects/igniteui-i18n-core/src/utils.ts @@ -0,0 +1,84 @@ +import type { PrefixedResourceStrings } from './i18n-manager.interfaces.js'; + +export const GRID_PREFIX = 'grid_'; +export const IGX_PREFIX = 'igx_'; + +/** Return if this is ran in browser environment or at least simulated one. */ +export function isBrowser() { + return typeof window !== 'undefined' && typeof document !== 'undefined'; +} + +/** Group each valid symbol for custom format that is replaced later on. + * See `formatDateCustomFormat` for supported values. + * Any word that doesn't contains the listed letters are kept as is - (?:[^BEGHLMOSWYZabcdhmswyz']+) + * Any symbol like ', ^, * as well treat as a word - (?:'(?:[^']|'')*') + * Group any letter listed here and allow it to be repeated from a to b times (`{a, b}`) - (?:G{1,5}|y{1,4}|Y{1,4}|M{1,5}|L{1,5}|w{1,2}|W{1}|d{1,2}|E{1,6}|c{1,6}|a{1,5}|b{1,5}|B{1,5}|h{1,2}|H{1,2}|K{1,2}|m{1,2}|s{1,2}|S{1,3}|z{1,4}|Z{1,5}|O{1,4}) + * ^ These are the ones supported by `formatDateCustomFormat` + * Any white space ignore and combine into groups if more - ([\s\S]*) + */ +export const customFormatRegex = + /((?:[^BEGHLMOSWYZabcdhmswyz']+)|(?:'(?:[^']|'')*')|(?:G{1,5}|y{1,4}|Y{1,4}|M{1,5}|L{1,5}|w{1,2}|W{1}|d{1,2}|E{1,6}|c{1,6}|a{1,5}|b{1,5}|B{1,5}|h{1,2}|H{1,2}|K{1,2}|m{1,2}|s{1,2}|S{1,3}|z{1,4}|Z{1,5}|O{1,4}))([\s\S]*)/; + +/** Determine if string date is a representation of ISO 8601 date. + * Separate each part into a named groups for year, month, day, time and timezone. + */ +export const isoRegex = + /(?\d{4})-(?\d{1,2})(?:-(?\d{1,2}))?(?