diff --git a/.all-contributorsrc b/.all-contributorsrc deleted file mode 100644 index 2c10f4a..0000000 --- a/.all-contributorsrc +++ /dev/null @@ -1,45 +0,0 @@ -{ - "projectName": "emulsify-core", - "projectOwner": "fourkitchens", - "repoType": "github", - "repoHost": "https://github.com", - "files": [ - "README.md" - ], - "imageSize": 100, - "commit": true, - "commitConvention": "angular", - "contributors": [ - { - "login": "callinmullaney", - "name": "Callin Mullaney", - "avatar_url": "https://avatars.githubusercontent.com/u/369018?v=4", - "profile": "https://github.com/callinmullaney", - "contributions": ["code", "doc"] - }, - { - "login": "amazingrando", - "name": "Randy Oest", - "avatar_url": "https://avatars.githubusercontent.com/u/409903?v=4", - "profile": "https://github.com/amazingrando", - "contributions": ["code", "doc"] - }, - { - "login": "robherba", - "name": "Roberto Hernandez", - "avatar_url": "https://avatars.githubusercontent.com/u/9342274?v=4", - "profile": "https://github.com/robherba", - "contributions": ["code"] - }, - { - "login": "dependabot", - "name": "Dependabot", - "avatar_url": "https://avatars.githubusercontent.com/u/49699333?v=4", - "profile": "https://github.com/dependabot", - "contributions": ["maintenance"] - } - ], - - "contributorsPerLine": 6, - "skipCi": true -} \ No newline at end of file diff --git a/.cli/init.js b/.cli/init.js index 47690ba..b4625eb 100755 --- a/.cli/init.js +++ b/.cli/init.js @@ -1,22 +1,27 @@ #!/usr/bin/env node +/** + * @file Initializes a generated Emulsify project from project.emulsify.json. + */ + const fs = require('fs'); const path = require('path'); const yaml = require('js-yaml'); /** - * Returns a boolean indicating whether or not the given object is a literal object. + * Determine whether a value is a plain object. * - * @param {any} obj object who's type will be checked. - * @returns {boolean} boolean indicating whether or not the given obj is a literal object. + * @param {*} obj - Value to inspect. + * @returns {boolean} TRUE when the value is a plain object. */ const isObjectLiteral = (obj) => obj != null && obj.constructor.name === 'Object'; /** - * Attempts to require the project.emulsify.json file. + * Load project.emulsify.json from the generated project config directory. * - * @returns parsed project.emulsify.json file. + * @returns {Object} Parsed project.emulsify.json file. + * @throws {Error} When the config cannot be loaded. */ const getEmulsifyConfig = () => { try { @@ -31,9 +36,11 @@ const getEmulsifyConfig = () => { }; /** - * Throws if the given emulsify config file is invalid. + * Validate the minimal project configuration required for initialization. * - * @param {*} config emulsify project config, as loaded from a project.emulsify.json file. + * @param {*} config - Emulsify project config loaded from project.emulsify.json. + * @returns {void} + * @throws {Error} When required config values are missing or invalid. */ const validateEmulsifyConfig = (config) => { const prefix = 'Invalid project.emulsify.json config file'; @@ -68,11 +75,10 @@ const validateEmulsifyConfig = (config) => { }; /** - * Takes an array of objects describing the origin and destination of a given file, - * then moves each specified file according to it's to/from properties. + * Move generated starter files to their project-specific names. * - * @param {Array<{ to: string, from: string }>} files array of objects depicting the origin and destination of a given file. - * @returns void. + * @param {Array<{ to: string, from: string }>} files - Files to move. + * @returns {Array} Rename results. */ const renameFiles = (files) => files.map(({ from, to }) => @@ -80,24 +86,23 @@ const renameFiles = (files) => ); /** - * Takes a machineName, and returns a fn that, when called with a str, - * replaces all instances of `emulsify` with the given machineName. + * Create a replacer that swaps the starter machine name for the project name. * - * @param {string} machineName string that should replace emulsify. - * @returns {function} fn that when called with a str, replaces all instances of `emulsify` with the given machineName. + * @param {string} machineName - Machine name that should replace `emulsify`. + * @returns {Function} String replacer. */ const strReplaceEmulsify = (machineName) => (str) => str.replace(/emulsify/g, machineName); /** - * Loads a yml file at filePath, applies the functor to the contents of the file, and writes it. + * Load a YAML file, transform its parsed contents, and write it back. * - * @param {string} filePath path to the file that should be loaded, modified, and re-saved. - * @param {fn} functor fn that should return the new contents of the file, to be saved. - * @returns void. + * @param {string} filePath - File to load, modify, and save. + * @param {Function} functor - Function that returns the replacement YAML data. + * @returns {void} */ const applyToYmlFile = (filePath, functor) => { - if (!filePath || typeof filePath !== `string`) { + if (!filePath || typeof filePath !== 'string') { throw new Error( `Cannot modify a file without knowing how to access it: ${filePath}`, ); @@ -111,18 +116,17 @@ const applyToYmlFile = (filePath, functor) => { }; const main = () => { - // Load up config file, throw if none exists. + // Load the project config before mutating any generated files. const config = getEmulsifyConfig(); - // Validate config file, throw if it is missing - //properties or is otherwise malformed. + // Fail fast when required project metadata is missing or malformed. validateEmulsifyConfig(config); const { - project: { machineName, name }, + project: { machineName }, } = config; - // Move all files to their correct location. + // Rename starter files from the generic prefix to the project machine name. renameFiles([ { from: '../emulsify.info.yml', @@ -142,7 +146,7 @@ const main = () => { }, ]); - // Update info.yml file. + // Update info.yml values that Drupal reads from the generated theme. applyToYmlFile( path.join(__dirname, `../${machineName}.info.yml`), (info) => ({ @@ -152,7 +156,7 @@ const main = () => { }), ); - // Update breakpoint.yml file. + // Update breakpoint keys to match the renamed theme machine name. applyToYmlFile( path.join(__dirname, `../${machineName}.breakpoints.yml`), (breakpoints) => { diff --git a/.editorconfig b/.editorconfig index cf0dff6..a26349e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,4 +1,4 @@ -# Unix-style newlines with a newline ending every file +# Keep editor defaults aligned with Prettier and repository formatting. [*] indent_style = space indent_size = 2 diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT_TEMPLATE.md b/.github/ISSUE_TEMPLATE/BUG_REPORT_TEMPLATE.md index 8fa5f7c..af3daa5 100644 --- a/.github/ISSUE_TEMPLATE/BUG_REPORT_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT_TEMPLATE.md @@ -1,18 +1,24 @@ ### Describe the bug + _A clear and concise description of what the bug is._ ### Steps to reproduce the bug + Steps to reproduce the behavior: + 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error ### Expected behavior + A clear and concise description of what you expected to happen. ### Suggested solution or approach: + _(optional) Describe a solution or approach to your request that may help with implementation._ ### Additional context -_(optional) Add any other context or screenshots about the feature request here._ \ No newline at end of file + +_(optional) Add any other context or screenshots about the feature request here._ diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST_TEMPLATE.md b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST_TEMPLATE.md index 3f95e93..e452355 100644 --- a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST_TEMPLATE.md @@ -1,11 +1,15 @@ ### Emulsify Core Version: + - [1.0.0](https://github.com/emulsify-ds/emulsify-core/releases)): ### Description of the feature request: -_Please give as much information as possible_ + +_Please give as much information as possible_ ### Suggested solution or approach: + _(optional) Describe a solution or approach to your request that may help with implementation._ ### Additional context: -_(optional) Add any other context or screenshots about the feature request here._ \ No newline at end of file + +_(optional) Add any other context or screenshots about the feature request here._ diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 4d3bb76..baf1bd2 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,19 +1,24 @@ **This PR does the following:** + - Adds functionality bullet item - Fixes this or that bullet item - + ### Related Issue(s) + - [Title of the issue](https://github.com/emulsify-ds/emulsify-core/issues/1) ### Notes: + - (optional) Document any intentionally unfinished parts or known issues within this PR ### Functional Testing: + - [ ] Document steps that allow someone to fully test your code changes. Include screenshot and links when appropriate. ### Security + _Security checks that should be reviewed_ ### Accessibility -_Should this be checked for this feature?_ +_Should this be checked for this feature?_ diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 51c04de..ad3ac1a 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,6 +1,8 @@ +# Keeps npm dependency metadata current for the package root. version: 2 updates: - package-ecosystem: npm - directory: "/" + directory: '/' + # Weekly updates reduce churn while keeping dependencies maintained. schedule: interval: weekly diff --git a/.github/fixtures/release/drupal-sdc-src-components/project.emulsify.json b/.github/fixtures/release/drupal-sdc-src-components/project.emulsify.json new file mode 100644 index 0000000..0665620 --- /dev/null +++ b/.github/fixtures/release/drupal-sdc-src-components/project.emulsify.json @@ -0,0 +1,8 @@ +{ + "project": { + "platform": "drupal", + "name": "drupal-sdc-src-components", + "machineName": "drupal_sdc_src_components", + "singleDirectoryComponents": true + } +} diff --git a/.github/fixtures/release/drupal-sdc-src-components/src/components/card/_content.twig b/.github/fixtures/release/drupal-sdc-src-components/src/components/card/_content.twig new file mode 100644 index 0000000..2310575 --- /dev/null +++ b/.github/fixtures/release/drupal-sdc-src-components/src/components/card/_content.twig @@ -0,0 +1 @@ +

{{ content }}

diff --git a/.github/fixtures/release/drupal-sdc-src-components/src/components/card/card.asset.txt b/.github/fixtures/release/drupal-sdc-src-components/src/components/card/card.asset.txt new file mode 100644 index 0000000..7f0cabd --- /dev/null +++ b/.github/fixtures/release/drupal-sdc-src-components/src/components/card/card.asset.txt @@ -0,0 +1 @@ +drupal-sdc-asset diff --git a/.github/fixtures/release/drupal-sdc-src-components/src/components/card/card.component.yml b/.github/fixtures/release/drupal-sdc-src-components/src/components/card/card.component.yml new file mode 100644 index 0000000..5b9da7f --- /dev/null +++ b/.github/fixtures/release/drupal-sdc-src-components/src/components/card/card.component.yml @@ -0,0 +1,3 @@ +name: Card +props: + type: object diff --git a/.github/fixtures/release/drupal-sdc-src-components/src/components/card/card.js b/.github/fixtures/release/drupal-sdc-src-components/src/components/card/card.js new file mode 100644 index 0000000..8b2732b --- /dev/null +++ b/.github/fixtures/release/drupal-sdc-src-components/src/components/card/card.js @@ -0,0 +1,6 @@ +import template from './card.twig'; + +export default template({ + heading: 'Drupal SDC card', + content: 'Rendered from a Twig include.', +}); diff --git a/.github/fixtures/release/drupal-sdc-src-components/src/components/card/card.scss b/.github/fixtures/release/drupal-sdc-src-components/src/components/card/card.scss new file mode 100644 index 0000000..926200e --- /dev/null +++ b/.github/fixtures/release/drupal-sdc-src-components/src/components/card/card.scss @@ -0,0 +1,3 @@ +.card { + color: #135e96; +} diff --git a/.github/fixtures/release/drupal-sdc-src-components/src/components/card/card.twig b/.github/fixtures/release/drupal-sdc-src-components/src/components/card/card.twig new file mode 100644 index 0000000..249be0d --- /dev/null +++ b/.github/fixtures/release/drupal-sdc-src-components/src/components/card/card.twig @@ -0,0 +1,8 @@ +{% set attrs = { + class: bem('card', ['featured']), + 'data-fixture': 'drupal-sdc' +} %} +
+

{{ heading }}

+ {% include './_content.twig' %} +
diff --git a/.github/fixtures/release/generic-src-components/config/emulsify-core/vite/plugins.js b/.github/fixtures/release/generic-src-components/config/emulsify-core/vite/plugins.js new file mode 100644 index 0000000..660d16e --- /dev/null +++ b/.github/fixtures/release/generic-src-components/config/emulsify-core/vite/plugins.js @@ -0,0 +1,12 @@ +module.exports = [ + { + name: 'generic-fixture-vite-extension', + generateBundle() { + this.emitFile({ + type: 'asset', + fileName: 'extension-marker.txt', + source: 'config/emulsify-core/vite/plugins.js loaded\n', + }); + }, + }, +]; diff --git a/.github/fixtures/release/generic-src-components/project.emulsify.json b/.github/fixtures/release/generic-src-components/project.emulsify.json new file mode 100644 index 0000000..8904c32 --- /dev/null +++ b/.github/fixtures/release/generic-src-components/project.emulsify.json @@ -0,0 +1,7 @@ +{ + "project": { + "platform": "generic", + "name": "generic-src-components", + "machineName": "generic_src_components" + } +} diff --git a/.github/fixtures/release/generic-src-components/src/base/base.js b/.github/fixtures/release/generic-src-components/src/base/base.js new file mode 100644 index 0000000..8fa17fa --- /dev/null +++ b/.github/fixtures/release/generic-src-components/src/base/base.js @@ -0,0 +1 @@ +export const fixture = 'generic base'; diff --git a/.github/fixtures/release/generic-src-components/src/base/base.scss b/.github/fixtures/release/generic-src-components/src/base/base.scss new file mode 100644 index 0000000..f3169f8 --- /dev/null +++ b/.github/fixtures/release/generic-src-components/src/base/base.scss @@ -0,0 +1,3 @@ +.base { + color: #2f6f4e; +} diff --git a/.github/fixtures/release/generic-src-components/src/components/card/_content.twig b/.github/fixtures/release/generic-src-components/src/components/card/_content.twig new file mode 100644 index 0000000..2310575 --- /dev/null +++ b/.github/fixtures/release/generic-src-components/src/components/card/_content.twig @@ -0,0 +1 @@ +

{{ content }}

diff --git a/.github/fixtures/release/generic-src-components/src/components/card/card.asset.txt b/.github/fixtures/release/generic-src-components/src/components/card/card.asset.txt new file mode 100644 index 0000000..101e3db --- /dev/null +++ b/.github/fixtures/release/generic-src-components/src/components/card/card.asset.txt @@ -0,0 +1 @@ +generic-src-asset diff --git a/.github/fixtures/release/generic-src-components/src/components/card/card.js b/.github/fixtures/release/generic-src-components/src/components/card/card.js new file mode 100644 index 0000000..b809ebd --- /dev/null +++ b/.github/fixtures/release/generic-src-components/src/components/card/card.js @@ -0,0 +1,6 @@ +import template from './card.twig'; + +export const html = template({ + heading: 'Generic Twig card', + content: 'Compiled with generic platform behavior.', +}); diff --git a/.github/fixtures/release/generic-src-components/src/components/card/card.scss b/.github/fixtures/release/generic-src-components/src/components/card/card.scss new file mode 100644 index 0000000..b69d043 --- /dev/null +++ b/.github/fixtures/release/generic-src-components/src/components/card/card.scss @@ -0,0 +1,3 @@ +.card { + color: #4f5f9f; +} diff --git a/.github/fixtures/release/generic-src-components/src/components/card/card.twig b/.github/fixtures/release/generic-src-components/src/components/card/card.twig new file mode 100644 index 0000000..a27e6a1 --- /dev/null +++ b/.github/fixtures/release/generic-src-components/src/components/card/card.twig @@ -0,0 +1,8 @@ +{% set attrs = { + class: bem('card', ['generic']), + 'data-fixture': 'generic-src' +} %} +
+

{{ heading }}

+ {% include './_content.twig' %} +
diff --git a/.github/fixtures/release/large-twig-storybook/project.emulsify.json b/.github/fixtures/release/large-twig-storybook/project.emulsify.json new file mode 100644 index 0000000..a20c24d --- /dev/null +++ b/.github/fixtures/release/large-twig-storybook/project.emulsify.json @@ -0,0 +1,7 @@ +{ + "project": { + "platform": "generic", + "name": "large-twig-storybook", + "machineName": "large_twig_storybook" + } +} diff --git a/.github/fixtures/release/large-twig-storybook/src/components/gallery/gallery.stories.js b/.github/fixtures/release/large-twig-storybook/src/components/gallery/gallery.stories.js new file mode 100644 index 0000000..a6f8f1d --- /dev/null +++ b/.github/fixtures/release/large-twig-storybook/src/components/gallery/gallery.stories.js @@ -0,0 +1,13 @@ +import { renderTwig } from '@emulsify/core/storybook'; +import template from './gallery.twig'; + +export default { + title: 'Fixtures/Large Twig Storybook', +}; + +export const Default = { + render: renderTwig(template), + args: { + heading: 'Large Twig fixture', + }, +}; diff --git a/.github/fixtures/release/large-twig-storybook/src/components/gallery/gallery.twig b/.github/fixtures/release/large-twig-storybook/src/components/gallery/gallery.twig new file mode 100644 index 0000000..e4ef668 --- /dev/null +++ b/.github/fixtures/release/large-twig-storybook/src/components/gallery/gallery.twig @@ -0,0 +1,8 @@ + diff --git a/.github/fixtures/release/legacy-components/components/banner/banner.asset.txt b/.github/fixtures/release/legacy-components/components/banner/banner.asset.txt new file mode 100644 index 0000000..c8cdaff --- /dev/null +++ b/.github/fixtures/release/legacy-components/components/banner/banner.asset.txt @@ -0,0 +1 @@ +legacy-components-asset diff --git a/.github/fixtures/release/legacy-components/components/banner/banner.js b/.github/fixtures/release/legacy-components/components/banner/banner.js new file mode 100644 index 0000000..3da34bb --- /dev/null +++ b/.github/fixtures/release/legacy-components/components/banner/banner.js @@ -0,0 +1,5 @@ +import template from './banner.twig'; + +export default template({ + heading: 'Legacy banner', +}); diff --git a/.github/fixtures/release/legacy-components/components/banner/banner.scss b/.github/fixtures/release/legacy-components/components/banner/banner.scss new file mode 100644 index 0000000..447125a --- /dev/null +++ b/.github/fixtures/release/legacy-components/components/banner/banner.scss @@ -0,0 +1,3 @@ +.banner { + color: #7f3f1d; +} diff --git a/.github/fixtures/release/legacy-components/components/banner/banner.twig b/.github/fixtures/release/legacy-components/components/banner/banner.twig new file mode 100644 index 0000000..c42611a --- /dev/null +++ b/.github/fixtures/release/legacy-components/components/banner/banner.twig @@ -0,0 +1,3 @@ +
+

{{ heading }}

+
diff --git a/.github/fixtures/release/legacy-components/project.emulsify.json b/.github/fixtures/release/legacy-components/project.emulsify.json new file mode 100644 index 0000000..559969c --- /dev/null +++ b/.github/fixtures/release/legacy-components/project.emulsify.json @@ -0,0 +1,7 @@ +{ + "project": { + "platform": "generic", + "name": "legacy-components", + "machineName": "legacy_components" + } +} diff --git a/.github/fixtures/release/mixed-storybook/assets/images/fixture-logo.svg b/.github/fixtures/release/mixed-storybook/assets/images/fixture-logo.svg new file mode 100644 index 0000000..16108ae --- /dev/null +++ b/.github/fixtures/release/mixed-storybook/assets/images/fixture-logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/.github/fixtures/release/mixed-storybook/project.emulsify.json b/.github/fixtures/release/mixed-storybook/project.emulsify.json new file mode 100644 index 0000000..0753725 --- /dev/null +++ b/.github/fixtures/release/mixed-storybook/project.emulsify.json @@ -0,0 +1,7 @@ +{ + "project": { + "platform": "generic", + "name": "mixed-storybook", + "machineName": "mixed_storybook" + } +} diff --git a/.github/fixtures/release/mixed-storybook/src/components/card/card.stories.js b/.github/fixtures/release/mixed-storybook/src/components/card/card.stories.js new file mode 100644 index 0000000..af9a4bb --- /dev/null +++ b/.github/fixtures/release/mixed-storybook/src/components/card/card.stories.js @@ -0,0 +1,48 @@ +import React from 'react'; +import { renderTwig } from '@emulsify/core/storybook'; +import template from './card.twig'; + +export default { + title: 'Fixtures/Mixed Storybook', + render: renderTwig(template, { + context: (args) => ({ + ...args, + renderedBy: 'default-render', + }), + }), +}; + +export const TwigCard = { + args: { + heading: 'Twig fixture', + body: 'Rendered through the public Storybook helper.', + variant: 'featured', + }, +}; + +export const ReactCard = { + render: ({ heading, body }) => + React.createElement( + 'article', + { className: 'react-card' }, + React.createElement('h2', null, heading), + React.createElement('p', null, body), + ), + args: { + heading: 'React fixture', + body: 'Rendered as a regular React story.', + }, +}; + +export const LegacyTwigCard = ({ heading, body, variant }) => + template({ + heading, + body, + variant, + }); + +LegacyTwigCard.args = { + heading: 'Legacy Twig fixture', + body: 'Rendered through the compatibility decorator.', + variant: 'standard', +}; diff --git a/.github/fixtures/release/mixed-storybook/src/components/card/card.twig b/.github/fixtures/release/mixed-storybook/src/components/card/card.twig new file mode 100644 index 0000000..7760537 --- /dev/null +++ b/.github/fixtures/release/mixed-storybook/src/components/card/card.twig @@ -0,0 +1,13 @@ +
+

{{ heading }}

+

{{ body }}

+ {% if renderedBy %} + {{ renderedBy }} + {% endif %} + {% switch variant|default('standard') %} + {% case 'featured' or 'highlight' %} + Featured + {% default %} + Standard + {% endswitch %} +
diff --git a/.github/fixtures/release/structure-implementations/project.emulsify.json b/.github/fixtures/release/structure-implementations/project.emulsify.json new file mode 100644 index 0000000..e1676df --- /dev/null +++ b/.github/fixtures/release/structure-implementations/project.emulsify.json @@ -0,0 +1,16 @@ +{ + "project": { + "platform": "generic", + "name": "structure-implementations", + "machineName": "structure_implementations" + }, + "variant": { + "platform": "generic", + "structureImplementations": [ + { "name": "components", "directory": "./src/components/" }, + { "name": "foundation", "directory": "./src/foundation/" }, + { "name": "layout", "directory": "./src/layout/" }, + { "name": "tokens", "directory": "./src/tokens/" } + ] + } +} diff --git a/.github/fixtures/release/structure-implementations/src/components/button/button.asset.txt b/.github/fixtures/release/structure-implementations/src/components/button/button.asset.txt new file mode 100644 index 0000000..13be288 --- /dev/null +++ b/.github/fixtures/release/structure-implementations/src/components/button/button.asset.txt @@ -0,0 +1 @@ +structure-button-asset diff --git a/.github/fixtures/release/structure-implementations/src/components/button/button.js b/.github/fixtures/release/structure-implementations/src/components/button/button.js new file mode 100644 index 0000000..5ac7ec2 --- /dev/null +++ b/.github/fixtures/release/structure-implementations/src/components/button/button.js @@ -0,0 +1,5 @@ +import template from './button.twig'; + +export const html = template({ + label: 'Structure button', +}); diff --git a/.github/fixtures/release/structure-implementations/src/components/button/button.scss b/.github/fixtures/release/structure-implementations/src/components/button/button.scss new file mode 100644 index 0000000..3a15388 --- /dev/null +++ b/.github/fixtures/release/structure-implementations/src/components/button/button.scss @@ -0,0 +1,3 @@ +.button { + color: #124f5a; +} diff --git a/.github/fixtures/release/structure-implementations/src/components/button/button.twig b/.github/fixtures/release/structure-implementations/src/components/button/button.twig new file mode 100644 index 0000000..3964a72 --- /dev/null +++ b/.github/fixtures/release/structure-implementations/src/components/button/button.twig @@ -0,0 +1,3 @@ + diff --git a/.github/fixtures/release/structure-implementations/src/foundation/colors/colors.js b/.github/fixtures/release/structure-implementations/src/foundation/colors/colors.js new file mode 100644 index 0000000..7394c4d --- /dev/null +++ b/.github/fixtures/release/structure-implementations/src/foundation/colors/colors.js @@ -0,0 +1 @@ +export const colors = ['blue', 'green']; diff --git a/.github/fixtures/release/structure-implementations/src/foundation/colors/colors.scss b/.github/fixtures/release/structure-implementations/src/foundation/colors/colors.scss new file mode 100644 index 0000000..091dbd7 --- /dev/null +++ b/.github/fixtures/release/structure-implementations/src/foundation/colors/colors.scss @@ -0,0 +1,3 @@ +.color-swatch { + color: #124f5a; +} diff --git a/.github/fixtures/release/structure-implementations/src/foundation/colors/palette.json b/.github/fixtures/release/structure-implementations/src/foundation/colors/palette.json new file mode 100644 index 0000000..0f62dcd --- /dev/null +++ b/.github/fixtures/release/structure-implementations/src/foundation/colors/palette.json @@ -0,0 +1,3 @@ +{ + "blue": "#124f5a" +} diff --git a/.github/fixtures/release/structure-implementations/src/layout/grid/grid.twig b/.github/fixtures/release/structure-implementations/src/layout/grid/grid.twig new file mode 100644 index 0000000..0e03315 --- /dev/null +++ b/.github/fixtures/release/structure-implementations/src/layout/grid/grid.twig @@ -0,0 +1,4 @@ +
+ {% include '@components/button/button.twig' with { label: 'Nested button' } %} + +
diff --git a/.github/fixtures/release/structure-implementations/src/layout/grid/sb-grid.scss b/.github/fixtures/release/structure-implementations/src/layout/grid/sb-grid.scss new file mode 100644 index 0000000..c6fa219 --- /dev/null +++ b/.github/fixtures/release/structure-implementations/src/layout/grid/sb-grid.scss @@ -0,0 +1,3 @@ +.sb-grid { + display: grid; +} diff --git a/.github/fixtures/release/structure-implementations/src/tokens/spacing/spacing.json b/.github/fixtures/release/structure-implementations/src/tokens/spacing/spacing.json new file mode 100644 index 0000000..c1688c4 --- /dev/null +++ b/.github/fixtures/release/structure-implementations/src/tokens/spacing/spacing.json @@ -0,0 +1,3 @@ +{ + "space-2": "0.5rem" +} diff --git a/.github/workflows/addtoprojects.yml b/.github/workflows/addtoprojects.yml index 15f0a63..6accd1f 100644 --- a/.github/workflows/addtoprojects.yml +++ b/.github/workflows/addtoprojects.yml @@ -1,3 +1,4 @@ +# Adds newly opened issues and pull requests to the shared Emulsify project board. name: Add to projects on: @@ -15,7 +16,6 @@ jobs: steps: - uses: actions/add-to-project@v0.3.0 with: - # You can target a repository in a different organization - # to the issue - project-url: https://github.com/emulsify-ds/emulsify-core - github-token: ${{ secrets.GH_TOKEN }} + # Keep triage in the organization-level project used by maintainers. + project-url: https://github.com/orgs/emulsify-ds/projects/6 + github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} diff --git a/.github/workflows/contributors.yml b/.github/workflows/contributors.yml index 966294e..2eae0cb 100644 --- a/.github/workflows/contributors.yml +++ b/.github/workflows/contributors.yml @@ -1,3 +1,4 @@ +# Regenerates contributor acknowledgements after maintained branch updates. name: Add contributors on: push: @@ -20,12 +21,13 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: "24" + node-version: '24.x' - name: Install all-contributors-cli run: npm install -g all-contributors-cli - name: Generate contributors + # Commit generated README changes back from the GitHub Actions identity. run: | all-contributors generate git config --global user.name 'GitHub Actions' diff --git a/.github/workflows/develop-version-bump.yml b/.github/workflows/develop-version-bump.yml new file mode 100644 index 0000000..1150e00 --- /dev/null +++ b/.github/workflows/develop-version-bump.yml @@ -0,0 +1,46 @@ +# Updates package metadata when semantic commits land on develop. +name: Develop Version Bump + +on: + push: + branches: [develop] + +permissions: + contents: write + +concurrency: + group: develop-version-bump + cancel-in-progress: false + +jobs: + version-bump: + name: Update package version + if: github.ref == 'refs/heads/develop' && github.actor != 'github-actions[bot]' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: '24.x' + - name: Install + run: npm install + - name: Update version from semantic commits + run: npm run version:develop -- "${{ github.event.before }}" "${{ github.sha }}" + - name: Commit package version + run: | + if git diff --quiet -- package.json package-lock.json; then + echo "No package version changes to commit." + exit 0 + fi + + NEXT_VERSION="$(node -p "require('./package.json').version")" + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add package.json package-lock.json + git commit -m "chore(release): bump version to ${NEXT_VERSION} [skip ci]" + git push origin HEAD:develop diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4ed0de5..d29b8fa 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,11 +1,12 @@ -name: Lint +# Runs release-readiness checks once for PR updates and after integration merges. +name: CI on: push: branches: [develop, main] pull_request: - branches: [develop, main] + branches: [4.x, develop, main] jobs: - build: + release-readiness: runs-on: ubuntu-latest steps: - name: Checkout @@ -15,8 +16,42 @@ jobs: - name: Install Node.js uses: actions/setup-node@v4 with: - node-version: "24" + node-version: '24.x' + cache: 'npm' - name: Install + # npm install validates the package the same way consumers install it. run: npm install - name: Lint run: npm run lint + - name: Test + run: npm test + - name: Storybook build + run: npm run storybook-build + fixture-builds: + name: Fixture / ${{ matrix.fixture }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + fixture: + - drupal-sdc-src-components + - generic-src-components + - legacy-components + - structure-implementations + - mixed-storybook + - large-twig-storybook + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: '24.x' + cache: 'npm' + - name: Install + # npm install validates the package the same way consumers install it. + run: npm install + - name: Fixture build + run: npm run fixtures:release -- --fixture ${{ matrix.fixture }} diff --git a/.github/workflows/semantic-release.yml b/.github/workflows/semantic-release.yml index ba0dab7..606db84 100644 --- a/.github/workflows/semantic-release.yml +++ b/.github/workflows/semantic-release.yml @@ -1,3 +1,4 @@ +# Publishes GitHub release metadata when changes land on main. name: Semantic Release on Merge on: push: @@ -14,10 +15,11 @@ jobs: - name: Install Node.js uses: actions/setup-node@v4 with: - node-version: "24.x" + node-version: '24.x' - name: Install run: npm install - name: Release + # Semantic Release reads commit history and repository tokens from CI. env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index 1a28bcc..2e3a9a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +# Keep generated outputs and local tooling files out of source control. + # Ignore compiled files. dist diff --git a/.husky/commit-msg b/.husky/commit-msg index 82f712f..e5ecc5c 100755 --- a/.husky/commit-msg +++ b/.husky/commit-msg @@ -1,2 +1,3 @@ #!/bin/sh +# Run commitlint through npm so local and CI hook behavior stay aligned. npm run husky:commit-msg diff --git a/.husky/pre-commit b/.husky/pre-commit index 0aea6e1..2a9cd43 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,2 +1,3 @@ #!/bin/sh +# Run the project lint task before commits are created. npm run husky:pre-commit diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..6462b13 --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +# Enforce the Node.js floor declared in package.json during npm installs. +engine-strict=true diff --git a/.prettierignore b/.prettierignore index c45aa50..e49384c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,5 @@ +# Ignore generated and dependency artifacts that should not be reformatted. dist .out .coverage -*.min.js \ No newline at end of file +*.min.js diff --git a/.storybook/_drupal.js b/.storybook/_drupal.js index fe71e65..23b5e9a 100644 --- a/.storybook/_drupal.js +++ b/.storybook/_drupal.js @@ -1,10 +1,14 @@ -// Simple Drupal.behaviors usage for Storybook +/** + * @file Minimal Drupal.behaviors compatibility layer for Storybook. + */ /** * Global Drupal namespace stub for Storybook environment. * @namespace Drupal */ -window.Drupal = { behaviors: {} }; +window.drupalSettings = window.drupalSettings || {}; +window.Drupal = window.Drupal || {}; +window.Drupal.behaviors = window.Drupal.behaviors || {}; /** * Immediately-Invoked Function Expression to scope Drupal behavior attachment logic. @@ -32,18 +36,18 @@ window.Drupal = { behaviors: {} }; Drupal.attachBehaviors = function (context, settings) { context = context || document; settings = settings || drupalSettings; - /** @type {Array<{attach?: Function}>} */ - const behaviors = Object.values(Drupal.behaviors); + /** @type {Object.} */ + const behaviors = Drupal.behaviors; - // Iterate through each behavior and invoke its attach method if defined. - behaviors.forEach(function (behavior) { - if (typeof behavior.attach === 'function') { + // Attach each registered behavior while isolating individual failures. + Object.keys(behaviors).forEach(function (i) { + if (typeof behaviors[i].attach === 'function') { try { - behavior.attach(context, settings); + behaviors[i].attach(context, settings); } catch (e) { Drupal.throwError(e); } } }); }; -})(Drupal, window.drupalSettings); +})(window.Drupal, window.drupalSettings); diff --git a/.storybook/_drupal.test.js b/.storybook/_drupal.test.js new file mode 100644 index 0000000..1fae5e5 --- /dev/null +++ b/.storybook/_drupal.test.js @@ -0,0 +1,23 @@ +/** + * @file Tests for the Storybook Drupal behavior shim. + */ + +describe('Storybook Drupal behavior shim', () => { + afterEach(() => { + delete window.Drupal; + delete window.drupalSettings; + }); + + it('initializes Drupal behaviors and attaches existing behavior callbacks', async () => { + await import('./_drupal.js'); + + const context = document.createElement('section'); + const attach = jest.fn(); + window.Drupal.behaviors.example = { attach }; + + window.Drupal.attachBehaviors(context); + + expect(window.drupalSettings).toEqual({}); + expect(attach).toHaveBeenCalledWith(context, window.drupalSettings); + }); +}); diff --git a/.storybook/emulsifyTheme.js b/.storybook/emulsifyTheme.js index 691a735..a7e2a91 100644 --- a/.storybook/emulsifyTheme.js +++ b/.storybook/emulsifyTheme.js @@ -1,16 +1,21 @@ -// Documentation on theming Storybook: https://storybook.js.org/docs/configurations/theming/ +/** + * @file Default Emulsify theme for the Storybook manager UI. + * + * @see https://storybook.js.org/docs/configurations/theming/ + */ + import { create } from 'storybook/theming'; export default create({ base: 'dark', - // UI + // Storybook application chrome colors. appBg: '#00405B', appContentBg: '#00202E', appBorderColor: '#00405B', appBorderRadius: 4, - // Typography + // Typography is intentionally aligned with the design system brand. fontBase: '"Mona Sans", sans-serif', fontCode: 'monospace', @@ -29,9 +34,7 @@ export default create({ inputBorder: '#00405B', inputTextColor: 'white', inputBorderRadius: 4, - // Branding + // Branding links the manager back to the public Emulsify site. brandTitle: 'Emulsify', brandUrl: 'https://emulsify.info', - brandImage: - 'https://raw.githubusercontent.com/fourkitchens/emulsify-core/main/assets/images/emulsify-logo-sb.svg', }); diff --git a/.storybook/main.js b/.storybook/main.js index 19953c2..b280c5b 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,20 +1,48 @@ -// .storybook/main.js - /** - * Storybook main configuration file. - * This configures stories, static directories, addons, core builder, - * framework, documentation settings, manager head styles, and overrides. + * Central Storybook configuration for Emulsify. + * + * This shared config defines the default Storybook behavior for consumers of + * the package, then lets a project layer local overrides on top at the end. + * The main custom behavior here is: + * - injecting manager/preview head markup + * - adapting the shared Vite config for Storybook + * - wiring Twig template discovery into the Storybook build + * * @module .storybook/main */ -import { resolve } from 'path'; import fs from 'fs'; -import path from 'path'; -import { fileURLToPath } from 'url'; -import { createRequire } from 'module'; -import extendWebpackConfig from './webpack.config.js'; +import path, { resolve } from 'path'; +import { fileURLToPath, pathToFileURL } from 'url'; +import viteConfig from '../config/vite/vite.config.js'; +import { resolveEnvironment } from '../config/vite/environment.js'; +import { + mergeReactSingletonOptimizeDeps, + mergeReactSingletonResolve, +} from '../config/vite/utils/react-singleton.js'; +import { + applyStorybookConfigOverrides, + normalizeStorybookConfigOverrideModule, +} from '../src/storybook/main-config.js'; + +// Twig glob maps are provided by config/vite/plugins/virtual-twig-globs.js. -const require = createRequire(import.meta.url); +/** + * Minimal subset of the resolved Emulsify environment used by this file. + * + * @typedef {object} StorybookEnvironment + * @property {string} projectDir - Absolute path to the consuming project root. + * @property {boolean} [structureOverrides] - Whether custom structure roots are enabled. + * @property {string[]} [structureRoots] - Absolute component root paths when overrides are active. + * @property {string[]} [componentRoots] - Absolute component roots in resolution order. + * @property {Record} [namespaceRoots] - Twig namespace roots. + * @property {string} [srcDir] - Absolute path to the project's `src` directory when present. + */ + +/** + * Storybook config type used for editor hints in this plain JS file. + * @typedef {import('@storybook/core-common').StorybookConfig} StorybookConfig + */ /** * The full path to the current file (ESM compatible). @@ -29,114 +57,179 @@ const _filename = fileURLToPath(import.meta.url); const _dirname = path.dirname(_filename); /** - * Migrate the consumer Storybook theme import from "@storybook/theming" to - * "storybook/theming" when needed. + * Reads an optional HTML fragment relative to this config file. * - * This runs opportunistically during startup and never throws so Storybook - * startup is resilient across all projects. + * Missing files are treated as empty content so downstream projects can opt in + * to extra markup without making Storybook fail on startup. + * + * @param {string} relativePath - Relative path from this file to the HTML fragment. + * @returns {string} File contents when the fragment exists, otherwise an empty string. */ -const migrateConsumerThemeImport = () => { - try { - const themeConfigPath = resolve( - _dirname, - '../../../../config/emulsify-core/storybook/theme.js', - ); +function readOptionalHtmlFragment(relativePath) { + const fragmentPath = resolve(_dirname, relativePath); - if (!fs.existsSync(themeConfigPath)) { - return; - } + if (!fs.existsSync(fragmentPath)) { + return ''; + } - const originalThemeConfig = fs.readFileSync(themeConfigPath, 'utf8'); + return fs.readFileSync(fragmentPath, 'utf8'); +} - if (!originalThemeConfig.includes('@storybook/theming')) { - return; - } +/** + * Keeps Storybook static directory config aligned to the consuming project. + * + * Storybook errors when a declared static directory is absent, so only expose + * project asset directories that exist in the current workspace. + * + * @param {string[]} staticDirs - Absolute static directory paths. + * @returns {string[]} Existing static directory paths. + */ +function existingStaticDirs(staticDirs) { + return staticDirs.filter((staticDir) => fs.existsSync(staticDir)); +} - const migratedThemeConfig = originalThemeConfig.replace( - /(['"])@storybook\/theming\1/g, - '$1storybook/theming$1', - ); +/** + * Reads optional project-level Storybook overrides. + * + * Downstream projects can provide this file, but the shared config also needs + * to load in package-level smoke tests where that project file is absent. + * + * @returns {Promise<{ config: object|Function, extendConfig?: Function, replaceAddons: boolean }>} + * Consumer overrides. + */ +async function loadConfigOverrides() { + const overridePath = resolve( + _dirname, + '../../../../config/emulsify-core/storybook/main.js', + ); - if (migratedThemeConfig !== originalThemeConfig) { - fs.writeFileSync(themeConfigPath, migratedThemeConfig, 'utf8'); - } - } catch { - // Ignore migration failures so Storybook startup is never blocked. + if (!fs.existsSync(overridePath)) { + return normalizeStorybookConfigOverrideModule(); } -}; -migrateConsumerThemeImport(); + const configOverrides = await import(pathToFileURL(overridePath).href); + return normalizeStorybookConfigOverrideModule(configOverrides); +} + +/** + * Builds Storybook story globs from normalized project roots. + * + * Stories remain colocated with components, whether the project uses the + * recommended `src/components` layout, legacy root `components`, or explicit + * structure implementation directories. + * + * @param {StorybookEnvironment} env - Resolved project paths used by Storybook. + * @returns {string[]} Storybook story globs. + */ +function buildStoryGlobs(env) { + if (Array.isArray(env.projectStructure?.storyRoots)) { + return env.projectStructure.storyRoots.map((root) => + path + .resolve(root, '**/*.stories.@(js|jsx|ts|tsx)') + .split(path.sep) + .join('/'), + ); + } + + const roots = + env.structureOverrides && + Array.isArray(env.structureRoots) && + env.structureRoots.length + ? env.structureRoots + : [ + path.resolve(env.projectDir, 'src'), + path.resolve(env.projectDir, 'components'), + ]; + + return Array.from(new Set(roots.filter(Boolean))).map((root) => + path + .resolve(root, '**/*.stories.@(js|jsx|ts|tsx)') + .split(path.sep) + .join('/'), + ); +} /** * Safely apply any user-provided overrides or fall back to an empty object. * @type {object} */ -const safeConfigOverrides = (() => { - try { - const overridesModule = require('../../../../config/emulsify-core/storybook/main.js'); - return overridesModule.default || overridesModule || {}; - } catch { - return {}; - } -})(); +const safeConfigOverrides = await loadConfigOverrides(); + +/** + * Environment details shared across this Storybook config load. + * @type {StorybookEnvironment} + */ +const resolvedStorybookEnv = resolveEnvironment(); /** * Primary Storybook configuration object. - * @type {import('storybook/internal/types').StorybookConfig} + * @type {StorybookConfig} */ -const config = { +const baseConfig = { /** - * Patterns for locating story files under src or components directories. + * Discover stories from both supported component roots. + * + * This shared config supports projects that keep stories under `src` as well + * as projects that expose a top-level `components` directory. + * * @type {string[]} */ - stories: ['../../../../@(src|components)/**/*.stories.@(js|jsx|ts|tsx)'], + stories: buildStoryGlobs(resolvedStorybookEnv), /** - * Directories to serve as static assets in the Storybook build. + * Mount shared assets into Storybook's static file server. + * + * Anything referenced by URL inside stories should live in one of these + * directories so it works in both `storybook dev` and static builds. + * * @type {string[]} */ staticDirs: [ - '../../../../assets/images', - '../../../../assets/icons', - '../../../../dist', - '../../../../assets/videos', + ...existingStaticDirs([ + path.resolve(process.cwd(), 'assets/images'), + path.resolve(process.cwd(), 'assets/icons'), + path.resolve(process.cwd(), 'dist'), + ]), ], /** - * List of Storybook addons to enable various features. + * Enable the default addon set used by Emulsify. + * + * `a11y` adds accessibility tooling, `links` supports story-to-story + * navigation, and `themes` exposes theme switching in the Storybook UI. + * * @type {string[]} */ addons: [ '@storybook/addon-a11y', '@storybook/addon-links', '@storybook/addon-themes', - '@storybook/addon-styling-webpack', ], /** - * Core builder configuration for Storybook. - * Storybook 9 splits the HTML renderer from the webpack builder, so the - * builder must be declared explicitly instead of relying on html-webpack5. - * @type {{builder: {name: string}, disableTelemetry: boolean}} + * Force the Vite builder and disable Storybook telemetry for shared usage. + * @type {{builder: string, disableTelemetry: boolean}} */ core: { - builder: { - name: '@storybook/builder-webpack5', - }, + builder: '@storybook/builder-vite', disableTelemetry: true, }, /** - * Framework specification for Storybook's HTML renderer. + * Tell Storybook to use the React + Vite framework package. * @type {{name: string, options: object}} */ framework: { - name: '@storybook/server-webpack5', + name: '@storybook/react-vite', options: {}, }, /** - * Documentation settings for Storybook autodocs. + * Disable automatic docs generation. + * + * Storybook will only render documentation pages that are authored + * explicitly instead of generating them from component metadata. + * * @type {{autodocs: boolean}} */ docs: { @@ -144,13 +237,17 @@ const config = { }, /** - * Custom styles injected into the Storybook manager (sidebar) head, - * plus any external manager-head.html snippet. - * @param {string} head - Existing head HTML. - * @returns {string} Modified head HTML. + * Appends Emulsify branding to the Storybook manager UI. + * + * This only affects Storybook's chrome, such as the sidebar, toolbar, and + * addon panels. It does not affect the iframe where stories actually render. + * + * @param {string} head - Existing manager head markup provided by Storybook. + * @returns {string} Manager head markup with Emulsify additions appended. */ managerHead: (head) => { - // inline theme styles + // Keep the manager styling inline so consumers inherit the branded UI + // without having to maintain a separate manager-only stylesheet. const inlineStyles = ` `; - - // load external manager-head.html if present - const externalManagerHeadPath = resolve( - _dirname, + const externalManagerHtml = readOptionalHtmlFragment( '../../../../config/emulsify-core/storybook/manager-head.html', ); - let externalManagerHtml = ''; - if (fs.existsSync(externalManagerHeadPath)) { - externalManagerHtml = fs.readFileSync(externalManagerHeadPath, 'utf8'); - } return `${head} -${inlineStyles} -${externalManagerHtml}`; + ${inlineStyles} + ${externalManagerHtml}`; }, /** - * Function to load and append an external preview-head.html into the preview iframe. - * @param {string} head - Existing preview head HTML. - * @returns {string} Combined head HTML including external snippet if present. + * Appends project-level head markup to the story preview iframe. + * + * This is the place for preview-only fonts, scripts, or meta tags that the + * rendered component output depends on. + * + * @param {string} head - Existing preview head markup provided by Storybook. + * @returns {string} Preview head markup with optional project HTML appended. */ previewHead: (head) => { - const externalHeadPath = resolve( - _dirname, + const externalHtml = readOptionalHtmlFragment( '../../../../config/emulsify-core/storybook/preview-head.html', ); - let externalHtml = ''; - if (fs.existsSync(externalHeadPath)) { - externalHtml = fs.readFileSync(externalHeadPath, 'utf8'); - } - return `${head} -${externalHtml}`; + ${externalHtml}`; }, /** - * Forward Storybook 9's webpack hook to the existing shared webpack helper so - * custom Twig, Sass, YAML, and resolver behavior still applies. - * @param {object} storybookConfig - Storybook's generated webpack config. - * @param {object} options - Storybook webpack hook options. - * @returns {Promise} The merged webpack config. + * Merges Storybook's generated Vite config with Emulsify's shared Vite config. + * + * Storybook supplies a baseline config, but Emulsify still needs to expose + * the resolved environment, expand filesystem access, and expose the Twig + * virtual glob module used by the runtime resolver. + * + * @param {import('vite').UserConfig} config - Storybook's generated Vite config. + * @returns {Promise} Final Vite config used by Storybook. */ - webpackFinal: async (storybookConfig, options) => - extendWebpackConfig({ config: storybookConfig, ...options }), + async viteFinal(config) { + const { mergeConfig } = await import('vite'); + /** @type {StorybookEnvironment} */ + const env = resolvedStorybookEnv; + + // Keep using the `serve` branch of the shared Vite config here. Storybook + // has historically consumed that branch, while `mode` still reflects + // whether Storybook is running in development or production. + const mode = config?.mode || 'development'; + const baseViteConfig = + typeof viteConfig === 'function' + ? await viteConfig({ command: 'serve', mode }) + : viteConfig; + const existingDefine = (config && config.define) || {}; + const viteDefine = (baseViteConfig && baseViteConfig.define) || {}; + + // Allow Storybook's dev server to read component sources from the project + // root and any structure override paths used by Emulsify consumers. + const allowList = new Set([ + ...(config?.server?.fs?.allow || []), + env.projectDir, + path.resolve(env.projectDir, 'src'), + path.resolve(env.projectDir, 'components'), + path.resolve(env.projectDir, 'dist'), + ...(Array.isArray(env.projectStructure?.sourceRoots) + ? env.projectStructure.sourceRoots + : []), + ...(Array.isArray(env.componentRoots) ? env.componentRoots : []), + ...(Array.isArray(env.structureRoots) ? env.structureRoots : []), + ...(env.namespaceRoots && typeof env.namespaceRoots === 'object' + ? Object.values(env.namespaceRoots) + : []), + ]); + + // Twig files are loaded through custom resolvers/plugins, so they need to + // be treated as importable assets by Storybook's Vite pipeline. + const assetsInclude = Array.from( + new Set([ + ...(config.assetsInclude || []), + ...(baseViteConfig.assetsInclude || []), + '**/*.twig', + ]), + ); + const optimizeDepsInclude = mergeReactSingletonOptimizeDeps( + baseViteConfig?.optimizeDeps?.include, + config?.optimizeDeps?.include, + [ + 'twig', + '@emulsify/core/extensions/twig', + ...(env.platformAdapter?.storybook?.registerDrupalTwigFilters + ? ['twig-drupal-filters'] + : []), + ], + ); - // Merge in user overrides without modifying original logic - ...safeConfigOverrides, + const mergedConfig = mergeConfig(config, { + ...baseViteConfig, + resolve: mergeReactSingletonResolve(baseViteConfig, config), + define: { + // Preserve shared and Storybook-provided constants, then publish the + // resolved Emulsify environment to client-side code. + ...viteDefine, + ...existingDefine, + __EMULSIFY_ENV__: JSON.stringify(env), + 'globalThis.__EMULSIFY_ENV__': JSON.stringify(env), + }, + server: { + ...(baseViteConfig?.server || {}), + fs: { + allow: Array.from(allowList), + }, + }, + assetsInclude, + plugins: [...(baseViteConfig?.plugins || [])], + esbuild: { + // Some downstream code is authored as `.js` files containing JSX, so + // keep Storybook's esbuild settings aligned with the shared Vite config. + jsx: 'automatic', + loader: 'jsx', + include: /.*\.jsx?$/, + exclude: [], + }, + optimizeDeps: { + ...(baseViteConfig?.optimizeDeps || {}), + ...(config?.optimizeDeps || {}), + include: optimizeDepsInclude, + esbuildOptions: { + ...(baseViteConfig?.optimizeDeps?.esbuildOptions || {}), + ...(config?.optimizeDeps?.esbuildOptions || {}), + loader: { + ...(baseViteConfig?.optimizeDeps?.esbuildOptions?.loader || {}), + ...(config?.optimizeDeps?.esbuildOptions?.loader || {}), + // Pre-bundle `.js` dependencies with the JSX loader for packages + // that ship JSX without a `.jsx` extension. + '.js': 'jsx', + }, + }, + }, + }); + + return { + ...mergedConfig, + resolve: mergeReactSingletonResolve(mergedConfig), + optimizeDeps: { + ...(mergedConfig.optimizeDeps || {}), + include: mergeReactSingletonOptimizeDeps( + mergedConfig.optimizeDeps?.include, + ), + esbuildOptions: { + ...(mergedConfig.optimizeDeps?.esbuildOptions || {}), + loader: { + ...(mergedConfig.optimizeDeps?.esbuildOptions?.loader || {}), + '.js': 'jsx', + }, + }, + }, + }; + }, }; +/** + * Primary Storybook configuration after project overrides have been applied. + * Project `addons` append to Emulsify defaults unless replacement is requested. + * + * @type {StorybookConfig} + */ +const config = await applyStorybookConfigOverrides( + baseConfig, + safeConfigOverrides, + { env: resolvedStorybookEnv }, +); + export default config; diff --git a/.storybook/main.test.js b/.storybook/main.test.js new file mode 100644 index 0000000..25787a2 --- /dev/null +++ b/.storybook/main.test.js @@ -0,0 +1,54 @@ +/** + * @file Tests for the shared Storybook main config. + */ + +import { execFileSync } from 'node:child_process'; + +describe('Storybook main config', () => { + it('dedupes React runtime modules in the final Vite config', async () => { + const script = ` + const { default: config } = await import('./.storybook/main.js'); + const finalConfig = await config.viteFinal({ + mode: 'development', + resolve: { + dedupe: ['example', 'react'], + }, + optimizeDeps: { + include: ['example-dep', 'react'], + }, + server: { + fs: { + allow: [], + }, + }, + }); + console.log(JSON.stringify({ + dedupe: finalConfig.resolve.dedupe, + include: finalConfig.optimizeDeps.include, + })); + `; + const output = execFileSync(process.execPath, [ + '--input-type=module', + '--eval', + script, + ]); + const finalConfig = JSON.parse(output.toString()); + + expect(finalConfig.dedupe).toEqual([ + 'example', + 'react', + 'react-dom', + 'react/jsx-runtime', + 'react/jsx-dev-runtime', + ]); + expect(finalConfig.include).toEqual([ + 'example-dep', + 'react', + 'twig', + '@emulsify/core/extensions/twig', + 'react-dom', + 'react/jsx-runtime', + 'react/jsx-dev-runtime', + ]); + }); +}); diff --git a/.storybook/manager.js b/.storybook/manager.js index 5dbe666..104dc6e 100644 --- a/.storybook/manager.js +++ b/.storybook/manager.js @@ -1,7 +1,9 @@ -// .storybook/manager.js +/** + * @file Storybook manager bootstrap and theme selection. + */ import { addons } from 'storybook/manager-api'; -import emulsifyTheme from './emulsifyTheme.js'; +import emulsifyTheme from './emulsifyTheme'; /** * Dynamically import the user-provided Storybook theme override. @@ -9,37 +11,28 @@ import emulsifyTheme from './emulsifyTheme.js'; */ import('../../../../config/emulsify-core/storybook/theme') /** - * Handle successful dynamic import of the theme module. + * Apply a project theme override when one exists. + * * @param {{ default: object }} module - The imported theme module. */ .then(({ default: customTheme }) => { - /** - * Determine if the imported theme object is empty or not. - * @type {boolean} - */ + // Empty override files should still fall back to the package theme. const isEmptyObject = !customTheme || (typeof customTheme === 'object' && Object.keys(customTheme).length === 0); - /** - * Apply the chosen theme to Storybook’s manager UI configuration. - * @type {{ theme: object }} - */ addons.setConfig({ theme: isEmptyObject ? emulsifyTheme : customTheme, }); }) /** - * Handle failure of the dynamic import (e.g., file not found). + * Fall back to the default theme when the project override is absent. + * * @returns {void} */ .catch(() => { addons.setConfig({ - /** - * Fallback to the default Emulsify theme on import error. - * @type {{ theme: object }} - */ theme: emulsifyTheme, }); }); diff --git a/.storybook/polyfills/twig-include.js b/.storybook/polyfills/twig-include.js deleted file mode 100644 index 84e4648..0000000 --- a/.storybook/polyfills/twig-include.js +++ /dev/null @@ -1,40 +0,0 @@ -import resolveTemplate from './twig-resolver.js'; - -/** - * Twig `include()` polyfill. - * Mirrors Drupal behaviour inside Storybook. - * @param {string} templateName - * @param {Object} [variables] - * @param {boolean} [withContext=false] - * @return {string} - */ -function twigInclude(Twig) { - Twig.extendFunction('include', (...args) => { - let [templateName, variables = {}, withContext = false] = args; - if ( - typeof withContext !== 'boolean' && - variables && - typeof variables.with_context !== 'undefined' - ) { - withContext = variables.with_context; - delete variables.with_context; - } - - try { - const templateFn = resolveTemplate(templateName); - if (!templateFn) return ''; - - const finalContext = - withContext && typeof this === 'object' - ? { ...(this.context || {}), ...variables } - : variables; - - return templateFn(finalContext); - } catch (err) { - console.error(`Twig include() failed for: ${templateName}`, err); - return ''; - } - }); -} - -export default twigInclude; diff --git a/.storybook/polyfills/twig-resolver.js b/.storybook/polyfills/twig-resolver.js deleted file mode 100644 index 77f4089..0000000 --- a/.storybook/polyfills/twig-resolver.js +++ /dev/null @@ -1,70 +0,0 @@ -import { getProjectMachineName } from '../utils.js'; - -const namespace = getProjectMachineName(); - -const twigComponents = require.context( - '../../../../../src/components/', - true, - /\.twig$/, -); - -/** - * Resolve template identifier to compiled Twig function. - * Supports: @component.twig, namespace:component, @namespace/component, namespace/component - * @param {string} name Template identifier - * @returns {Function|undefined} Compiled function or noop - */ -function resolveTemplate(name) { - // namespace:icon, @namespace/icon.twig - if (name.startsWith(`${namespace}:`) || name.startsWith(`@${namespace}/`)) { - const part = name.startsWith(`${namespace}:`) - ? name.split(':')[1] - : name.replace(`${namespace}/`, '').replace('.twig', ''); - const path = `./${part}/${part}.twig`; - try { - const mod = twigComponents(path); - return mod && mod.default ? mod.default : mod; - } catch { - console.error(`Cannot resolve Twig component for '${name}' at '${path}'`); - } - } - - // @icon.twig → icon/icon.twig - if (name.startsWith('@') && name.endsWith('.twig')) { - const part = name.slice(1, -5); // remove leading @ and trailing .twig - const path = `./${part}/${part}.twig`; - try { - return twigComponents(path).default || twigComponents(path); - } catch { - console.error( - `Cannot resolve Twig shorthand template '${name}' at '${path}'`, - ); - } - } - - // namespace/icon.twig via webpack alias - if (name.startsWith(`${namespace}/`)) { - const part = name.slice(namespace.length + 1).replace('.twig', ''); - const path = `./${part}/${part}.twig`; - try { - return twigComponents(path).default || twigComponents(path); - } catch { - console.error( - `Cannot resolve Twig alias template '${name}' at '${path}'`, - ); - } - } - - try { - // Storybook resolves runtime Twig requests through webpack, so this - // fallback intentionally loads a module path determined at render time. - // eslint-disable-next-line security/detect-non-literal-require - const mod = require(name); - return mod && mod.default ? mod.default : mod; - } catch (error) { - console.error(`Cannot resolve Twig template '${name}'`, error); - return () => ''; - } -} - -export default resolveTemplate; diff --git a/.storybook/polyfills/twig-source.js b/.storybook/polyfills/twig-source.js deleted file mode 100644 index 941a7eb..0000000 --- a/.storybook/polyfills/twig-source.js +++ /dev/null @@ -1,65 +0,0 @@ -import { getProjectMachineName } from '../utils.js'; - -const namespace = getProjectMachineName(); - -// Constants used by the `source()` polyfill. -const PUBLIC_ASSET_BASE = - typeof window !== 'undefined' && - window.location && - window.location.hostname && - window.location.hostname.endsWith('github.io') - ? `/${namespace}/assets/` - : '/assets/'; - -const INLINE_ASSET_EXTS = new Set([ - 'svg', - 'html', - 'twig', - 'css', - 'js', - 'json', - 'txt', - 'md', -]); -const IMAGE_ASSET_EXTS = new Set(['png', 'jpg', 'jpeg', 'gif', 'webp', 'avif']); - -/** - * Twig `source()` polyfill. - * Returns an tag or URL for @assets paths. - * @param {string} assetPath - * @return {string} - */ -function twigSource(Twig) { - Twig.extendFunction('source', (assetPath) => { - if (typeof assetPath !== 'string') return ''; - - // Strip Drupal-style alias and extract file extension. - const relPath = assetPath.replace(/^@assets\//, ''); - const extension = relPath.split('.').pop().toLowerCase(); - - // Inline raw content for textual assets. - if (INLINE_ASSET_EXTS.has(extension)) { - try { - const xhr = new XMLHttpRequest(); - xhr.open('GET', `${PUBLIC_ASSET_BASE}${relPath}`, false); // synchronous - xhr.send(null); - if (xhr.status >= 200 && xhr.status < 300) { - return xhr.responseText; - } - console.error(`source(): ${xhr.status} while fetching ${relPath}`); - } catch (err) { - console.error(`source(): failed to fetch ${relPath}`, err); - } - } - - // Auto-render raster images. - if (IMAGE_ASSET_EXTS.has(extension)) { - return ``; - } - - // Fallback: return public URL. - return `${PUBLIC_ASSET_BASE}${relPath}`; - }); -} - -export default twigSource; diff --git a/.storybook/preview.js b/.storybook/preview.js index 0198f1b..b733949 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,31 +1,48 @@ -// .storybook/preview.js -import { useEffect } from 'storybook/preview-api'; -import Twig from 'twig'; -import { setupTwig, fetchCSSFiles } from './utils.js'; -import { getRules } from 'axe-core'; - /** - * External override parameters loaded from project config file, if present. - * @type {object} + * @file Storybook preview configuration shared by Emulsify projects. */ -let externalOverrides; -// Load the preview.js from the project config overrides. -try { - /** - * Dynamically require external preview overrides. - * @module '../../../../config/emulsify-core/storybook/preview.js' - */ - externalOverrides = - require('../../../../config/emulsify-core/storybook/preview.js').default; -} catch { - // no override file? swallow the error and use {} - externalOverrides = {}; +import { getRules } from 'axe-core'; +import React from 'react'; +import { defaultDecorateStory, useEffect } from 'storybook/preview-api'; +import Twig from 'twig'; +import { + mergePreviewParameters, + normalizePreviewOverrideModule, +} from '../src/storybook/preview-parameters.js'; +import { + renderHtmlStoryResult, + StoryHtmlBoundary, + withLegacyStoryToString, +} from '../src/storybook/render-twig.js'; +import { + attachStorybookBehaviors, + fetchCSSFiles, + getStorybookPlatformAdapter, + setupTwig, +} from './utils.js'; + +const previewOverrideModules = import.meta.glob( + [ + // Installed package path: node_modules/@emulsify/core/.storybook -> project root. + '../../../../config/emulsify-core/storybook/preview.js', + // Local development path: repo .storybook -> repo root. + '../config/emulsify-core/storybook/preview.js', + ], + { eager: true }, +); +const [previewOverrideModule] = Object.values(previewOverrideModules); +const externalOverrides = normalizePreviewOverrideModule(previewOverrideModule); + +const platformAdapter = getStorybookPlatformAdapter(); +const platformBehaviorShimReady = platformAdapter.loadDrupalBehaviorShim + ? import('./_drupal.js') + : Promise.resolve(); +const platformTwigExtensions = []; +if (platformAdapter.registerDrupalTwigFilters) { + platformTwigExtensions.push((await import('twig-drupal-filters')).default); } -// Import Drupal behaviors for rich JavaScript integration. -import './_drupal.js'; - /** * Filters accessibility rules by matching tags. * @param {string[]} [tags=[]] List of WCAG rule tags to enable. @@ -53,100 +70,57 @@ const AxeRules = enableRulesByTag([ 'best-practice', ]); -/** - * Cache of rendered story output keyed by story id. - * Storybook server renderer calls `storyFn()` before `fetchStoryHtml`, so - * decorators can stash markup here and fetch can read it without re-rendering. - * - * @type {Map} - */ -const renderedStoryCache = new Map(); - -/** - * Converts a rendered story return value into an HTML string. - * - * @param {unknown} rendered - * The rendered story result. - * - * @returns {string} - * Normalized HTML string. - */ -function toHtmlString(rendered) { - if (typeof rendered === 'string') { - return rendered; - } - - if (rendered && typeof rendered === 'object') { - if (typeof rendered.outerHTML === 'string') { - return rendered.outerHTML; - } - if (typeof rendered.html === 'string') { - return rendered.html; - } - } - - return ''; -} +// Initialize platform-agnostic Twig helpers and eager-load story CSS. +setupTwig(Twig, { extensions: platformTwigExtensions }); +fetchCSSFiles(); /** - * Default server renderer adapter for Storybook 9 server-webpack5. - * Falls back to local story functions so projects do not need a remote - * `parameters.server.url` endpoint for basic HTML/Twig stories. - * - * @param {string} _url - * Unused URL from server parameters. - * @param {string} _path - * Unused story path/id from server parameters. - * @param {object} _params - * Unused merged server params. - * @param {object} storyContext - * Story context from Storybook. + * Storybook React wraps story functions in React elements before decorators run. + * Preserve that React-safe behavior while giving old stringifying decorators a + * useful string result for legacy Twig stories. * - * @returns {Promise} - * Story markup as an HTML string. + * @param {Function} storyFn Storybook story function. + * @param {Function[]} decorators Storybook decorators. + * @returns {Function} Decorated story function. */ -async function fetchStoryHtmlFromStoryContext( - _url, - _path, - _params, - storyContext, -) { - const storyId = storyContext?.id || _path; - if (!storyId || !renderedStoryCache.has(storyId)) { - return ''; - } - - const rendered = await Promise.resolve(renderedStoryCache.get(storyId)); - return toHtmlString(rendered); -} - -// Initialize Twig and load any CSS that your stories need. -setupTwig(Twig); -fetchCSSFiles(); +export const applyDecorators = (storyFn, decorators) => + defaultDecorateStory( + (context) => + withLegacyStoryToString(React.createElement(storyFn, context), () => + storyFn(context), + ), + decorators, + ); /** - * Storybook decorators to apply Drupal behaviors before rendering each story. - * The HTML renderer still uses the generic Storybook decorator signature. - * @type {Function[]} + * Storybook decorators to apply platform-specific behavior after each story render. + * @type {Array} */ export const decorators = [ /** - * Decorator that attaches Drupal behaviors on story mount. + * Decorator that attaches platform behavior on story mount and args updates. + * Legacy Twig stories that return HTML strings are wrapped so React + * Storybook renders them as markup while projects migrate to renderTwig(). + * * @param {Function} Story The story component to render. * @param {object} context Story context including args. - * @returns {Function} Rendered story. + * @returns {*} Rendered story. */ - (Story, context) => { - const { args, id } = context; + (Story, { args }) => { useEffect(() => { - Drupal.attachBehaviors(); + void attachStorybookBehaviors({ + adapter: platformAdapter, + behaviorShimReady: platformBehaviorShimReady, + }); }, [args]); - const rendered = Story(); - if (id) { - renderedStoryCache.set(id, rendered); - } - return rendered; + return React.createElement( + StoryHtmlBoundary, + {}, + renderHtmlStoryResult(Story(), { + platformAdapter, + }), + ); }, ]; @@ -164,18 +138,13 @@ const defaultParams = { }, }, layout: 'fullscreen', - server: { - url: '', - fetchStoryHtml: fetchStoryHtmlFromStoryContext, - params: {}, - }, }; /** * Merged Storybook parameters including external overrides. * @type {object} */ -export const parameters = { - ...defaultParams, - ...externalOverrides, -}; +export const parameters = mergePreviewParameters( + defaultParams, + externalOverrides, +); diff --git a/.storybook/utils.js b/.storybook/utils.js index 30e1743..b53f33b 100644 --- a/.storybook/utils.js +++ b/.storybook/utils.js @@ -1,60 +1,61 @@ -import { resolve, dirname } from 'path'; -import twigDrupal from 'twig-drupal-filters'; -import twigBEM from 'bem-twig-extension'; -import twigAddAttributes from 'add-attributes-twig-extension'; -import emulsifyConfig from '../../../../project.emulsify.json' with { type: 'json' }; -import twigInclude from './polyfills/twig-include.js'; -import twigSource from './polyfills/twig-source.js'; +/** + * @file Shared Storybook runtime helpers. + */ -// Create __filename from import.meta.url without fileURLToPath -let _filename = decodeURIComponent(new URL(import.meta.url).pathname); +import { + attachStorybookBehaviors, + genericStorybookAdapter, + normalizeStorybookPlatformAdapter, +} from '../src/storybook/platform-behaviors.js'; +import { setupTwig } from '../src/storybook/twig/setup.js'; -// On Windows, remove the leading slash (e.g. "/C:/path" -> "C:/path") -if (process.platform === 'win32' && _filename.startsWith('/')) { - _filename = _filename.slice(1); -} +const emulsifyEnv = + (typeof __EMULSIFY_ENV__ !== 'undefined' && __EMULSIFY_ENV__) || {}; -const _dirname = dirname(_filename); +/** + * Get the normalized Emulsify environment injected by Storybook's Vite config. + * + * @returns {object} Normalized Emulsify environment. + */ +export function getEmulsifyEnvironment() { + return emulsifyEnv; +} /** - * Fetches project-based variant configuration. If no such configuration - * exists, returns default values as a flat component structure. + * Get Storybook platform behavior flags from the active adapter. * - * @returns {Array} project-based variant configuration, or default config. + * @returns {object} Storybook adapter flags. */ -const fetchVariantConfig = () => { - try { - return emulsifyConfig.variant.structureImplementations; - } catch { - return [ - { - name: 'components', - directory: '../../../../components', - }, - ]; - } -}; +export function getStorybookPlatformAdapter() { + return normalizeStorybookPlatformAdapter( + emulsifyEnv.platformAdapter?.storybook, + ); +} /** * Fetches and loads all CSS files from the specified directories based on the project's configuration. - * If the platform is 'drupal', it also includes CSS files from additional component directories. + * If the active platform adapter enables mirrored component CSS, those files + * are loaded in addition to the compiled dist CSS. * * @returns {undefined} If an error occurs, the function will return undefined. */ const fetchCSSFiles = () => { try { - // Load all CSS files from 'dist'. - const cssFiles = require.context('../../../../dist', true, /\.css$/); - cssFiles.keys().forEach((file) => cssFiles(file)); + const adapter = getStorybookPlatformAdapter(); - // Load all CSS files from 'components' for 'drupal' platform. - if (emulsifyConfig.project.platform === 'drupal') { - const drupalCSSFiles = require.context( - '../../../../components', - true, - /\.css$/, + // Load compiled CSS from dist for both development and static previews. + const cssFiles = import.meta.glob('../../../../dist/**/*.css', { + eager: true, + }); + Object.values(cssFiles).forEach((css) => css); + + // Platform adapters decide whether root component CSS is expected. + if (adapter.loadMirroredComponentCss) { + const mirroredCSSFiles = import.meta.glob( + '../../../../components/**/*.css', + { eager: true }, ); - drupalCSSFiles.keys().forEach((file) => drupalCSSFiles(file)); + Object.values(mirroredCSSFiles).forEach((css) => css); } } catch { return undefined; @@ -68,36 +69,16 @@ const fetchCSSFiles = () => { * @returns {string|undefined} Project machine name string, or undefined if not available */ export function getProjectMachineName() { - try { - return emulsifyConfig.project.machineName; - } catch { - return undefined; - } -} - -// Build namespaces mapping. -export const namespaces = Object.fromEntries( - fetchVariantConfig().map(({ name, directory }) => [ - name, - resolve(_dirname, '../../../../', directory), - ]), -); - -/** - * Configures and extends a standard Twig object. - * - * @param {Object} twig - Twig object that should be configured and extended. - * @returns {Object} Configured Twig object. - */ -export function setupTwig(twig) { - twig.cache(); - twigDrupal(twig); - twigBEM(twig); - twigAddAttributes(twig); - twigInclude(twig); - twigSource(twig); - return twig; + return typeof emulsifyEnv.machineName === 'string' + ? emulsifyEnv.machineName + : undefined; } -// Export the fetchCSSFiles function. -export { fetchCSSFiles }; +// Keep these named exports stable for preview.js and downstream overrides. +export { + attachStorybookBehaviors, + fetchCSSFiles, + genericStorybookAdapter, + normalizeStorybookPlatformAdapter, + setupTwig, +}; diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js deleted file mode 100644 index f61bed5..0000000 --- a/.storybook/webpack.config.js +++ /dev/null @@ -1,269 +0,0 @@ -import { dirname, resolve } from 'path'; -import { createRequire } from 'module'; -import globImporter from 'node-sass-glob-importer'; -import _StyleLintPlugin from 'stylelint-webpack-plugin'; -import webpack from 'webpack'; -import resolves from '../config/webpack/resolves.js'; -import emulsifyConfig from '../../../../project.emulsify.json' with { type: 'json' }; - -const require = createRequire(import.meta.url); - -// Create __filename from import.meta.url without fileURLToPath -let _filename = decodeURIComponent(new URL(import.meta.url).pathname); - -// On Windows, remove the leading slash (e.g. "/C:/path" -> "C:/path") -if (process.platform === 'win32' && _filename.startsWith('/')) { - _filename = _filename.slice(1); -} - -/** - * Directory name of the current file. - * @type {string} - */ -const _dirname = dirname(_filename); - -/** - * Absolute path to the project root directory. - * @type {string} - */ -const projectDir = resolve(_dirname, '../../../../..'); - -/** - * Webpack plugin to resolve custom namespace imports. - * Transforms `:` into `/` paths. - */ -class ProjectNameResolverPlugin { - /** - * @param {object} options - Plugin options. - * @param {string} options.projectName - Prefix for the project namespace. - */ - constructor(options = {}) { - this.prefix = options.projectName; - } - - /** - * Apply the webpack resolver hook. - * @param {object} resolver - The webpack resolver instance. - */ - apply(resolver) { - const target = resolver.ensureHook('resolve'); - resolver.getHook('before-resolve').tapAsync( - 'ProjectNameResolverPlugin', - /** - * @param {object} request - The resolve request object. - * @param {object} resolveContext - Context for resolving. - * @param {Function} callback - Callback to continue resolution. - */ - (request, resolveContext, callback) => { - const requestPath = request.request; - - if (requestPath && requestPath.startsWith(`${this.prefix}:`)) { - const newRequestPath = requestPath.replace( - `${this.prefix}:`, - `${this.prefix}/`, - ); - const newRequest = { - ...request, - request: newRequestPath, - }; - - resolver.doResolve( - target, - newRequest, - `Resolved ${this.prefix} URI`, - resolveContext, - callback, - ); - } else { - callback(); - } - }, - ); - } -} - -/** - * Export a function to customize the Webpack config for Storybook. - * @param {object} param0 - The Storybook configuration object. - * @param {object} param0.config - The existing webpack config to modify. - * @returns {object} The updated webpack config. - */ -export default async function ({ config }) { - config.resolve = config.resolve || {}; - config.plugins = config.plugins || []; - - config.module = config.module || {}; - config.module.rules = config.module.rules || []; - - const hasLoader = (rule, loaderName) => { - if (!rule) { - return false; - } - - if (typeof rule.loader === 'string' && rule.loader.includes(loaderName)) { - return true; - } - - const use = rule.use; - if (typeof use === 'string') { - return use.includes(loaderName); - } - if (Array.isArray(use)) { - return use.some((entry) => { - if (typeof entry === 'string') { - return entry.includes(loaderName); - } - return ( - entry && - typeof entry.loader === 'string' && - entry.loader.includes(loaderName) - ); - }); - } - - return false; - }; - - const hasRule = (testRegex, loaderName) => - config.module.rules.some( - (rule) => - rule && - rule.test && - String(rule.test) === String(testRegex) && - hasLoader(rule, loaderName), - ); - - const pushRuleOnce = (rule, loaderName) => { - if (!hasRule(rule.test, loaderName)) { - config.module.rules.push(rule); - } - }; - - // Alias - Object.assign(config.resolve.alias, resolves.TwigResolve.alias); - - // Twig loader - pushRuleOnce( - { - /** - * @type {RegExp} - */ - test: /\.twig$/, - use: [ - { - /** - * Custom loader for svg/spritemap integration. - * @type {string} - */ - loader: resolve(_dirname, '../config/webpack/sdc-loader.js'), - options: { - /** - * Name of the Emulsify project for resolving. - * @type {string} - */ - projectName: emulsifyConfig.project.name, - }, - }, - { - /** - * Standard Twig JS loader. - * @type {string} - */ - loader: 'twigjs-loader', - }, - ], - }, - 'twigjs-loader', - ); - - // SCSS Loader configuration - pushRuleOnce( - { - test: /\.s[ac]ss$/i, - use: [ - 'style-loader', - { - loader: 'css-loader', - options: { - /** - * Enable source maps for CSS. - * @type {boolean} - */ - sourceMap: true, - }, - }, - { - loader: 'sass-loader', - options: { - sourceMap: true, - sassOptions: { - importer: globImporter(), - }, - }, - }, - ], - }, - 'sass-loader', - ); - - // YAML loader - pushRuleOnce( - { - /** - * @type {RegExp} - */ - test: /\.ya?ml$/, - loader: 'js-yaml-loader', - }, - 'js-yaml-loader', - ); - - // Keep style linting in the Storybook webpack build. ESLint runs via the - // dedicated npm scripts instead, which avoids coupling Storybook to a - // specific ESLint major version. - config.plugins.push( - new _StyleLintPlugin({ - configFile: resolve(projectDir, '../', '.stylelintrc.json'), - context: resolve(projectDir, '../', 'src'), - files: '**/*.scss', - failOnError: false, - quiet: false, - }), - ); - - // Custom resolver plugin for namespaced imports - config.resolve.plugins = [ - new ProjectNameResolverPlugin({ - projectName: emulsifyConfig.project.name, - }), - ]; - - // Merge fallbacks so we do not clobber Storybook defaults. - config.resolve.fallback = { - ...(config.resolve.fallback || {}), - process: require.resolve('process/browser'), - /** - * Prevent resolution of components directory if missing. - */ - '../../../../components': false, - }; - - // Provide global `process` for browser bundles that pull in node-style libs. - const hasProcessProvidePlugin = config.plugins.some( - (plugin) => - plugin && - plugin.constructor && - plugin.constructor.name === 'ProvidePlugin' && - plugin.definitions && - Object.prototype.hasOwnProperty.call(plugin.definitions, 'process'), - ); - if (!hasProcessProvidePlugin) { - config.plugins.push( - new webpack.ProvidePlugin({ - process: 'process/browser', - }), - ); - } - - return config; -} diff --git a/README.md b/README.md index d56ebea..573b131 100644 --- a/README.md +++ b/README.md @@ -4,93 +4,143 @@ An open-source toolset for creating and implementing design systems. -**Emulsify Core** provides a [Storybook](https://storybook.js.org/) component library and a [Webpack](https://webpack.js.org/) development environment. It is meant to make project setup and ongoing development easier by bundling all necessary configuration and providing it as an extendable package for your theme or standalone project. +**Emulsify Core** provides shared [Vite](https://vite.dev/) build configuration and a [Storybook](https://storybook.js.org/) component library setup for component-driven development. Twig-based components and React components are both supported authoring models. A project can be Twig-first, React-first, or intentionally mixed. -## Installation and usage -Installation and configuration is setup by the provided base theme project(s). As of this writing, Emulsify Drupal is the only base theme project [with this integration](https://github.com/emulsify-ds/emulsify-drupal/blob/main/whisk/package.json#L36). +## How Emulsify Core Works -### Manual installation -- `npm install @emulsify/core` within your repository or project theme. -- Copy the provided `npm run` scripts from [Emulsify Drupal's package.json](https://github.com/emulsify-ds/emulsify-drupal/blob/main/whisk/package.json#L15) -- Copy the contents of `whisk/config/emulsify-core/` from [Emulsify Drupal](https://github.com/emulsify-ds/emulsify-drupal/tree/main/whisk/config/emulsify-core) into your project so `config/` exists at the root of your repository or project theme. The files within `config/` allow you to extend or overwrite configuration provided by Emulsify Core. +- Vite builds project JavaScript, Sass/CSS, Twig templates, component metadata, and static component assets. +- Storybook uses the React/Vite framework. +- Twig files can render in React-based Storybook through `renderTwig()`. +- React components render through Storybook's React/Vite support. +- Twig and React stories can coexist in the same Storybook instance. +- `project.emulsify.json` is the source of truth for platform and structure configuration. +- Platform-specific behavior is controlled by adapters instead of being assumed globally. +- Node.js 24 or later is required. -### Common Scripts +## Project Evolution -Run `nvm use` prior to running any of the following commands to verify you are using Node 20. -(Each is prefixed with `npm run `) +Emulsify Core has grown through each major release while keeping the same practical goal: make component-library tooling easier to share across real projects. -**develop** -Starts and instance of storybook, watches for any files changes, recompiles CSS/JS, and live reloads storybook assets. +- `1.x` established Emulsify Core as a reusable package for Storybook, Webpack, linting, a11y checks, project overrides, and asset handling. +- `2.x` expanded component structure support, improved Drupal SDC compatibility, upgraded Storybook, and made more project files configurable from consuming projects. +- `3.x` modernized the runtime around ESM and Node 24, continued Storybook and dependency upgrades, improved component asset copying, and strengthened compatibility for existing Drupal-oriented builds. +- The current release moves the build system to Vite, runs Storybook on React/Vite, supports Twig and React stories side by side, and normalizes platform and project-structure behavior through `project.emulsify.json`. -**lint** -Lints all JS/SCSS within your components and reports any violations. +The latest version is the next evolution of that work: faster builds, clearer public APIs, less global Drupal assumption, and a broader foundation for CMS themes, standalone UI libraries, and mixed component systems. -**lint-fix** -Automatically fixes any simple violations. +See [Version Evolution](docs/version-evolution.md) for more release history. -**prettier** -Outputs any code formatting violations. +## Authoring Models -**prettier-fix** -Automatically fixes any simple code formatting violations. +Twig and React are equally valid ways to build component libraries with Emulsify Core. The right authoring model depends on the consuming project: -**storybook-build** -Builds a static output of the storybook instance. +- Use Twig for CMS themes and server-rendered template systems. Drupal has a dedicated adapter today; Craft CMS and WordPress + Timber can use the generic adapter unless a project adds platform-specific behavior. +- Use React for standalone UI libraries, application components, or projects that already use React. +- Use mixed Twig and React when a design system needs to document both CMS-rendered and JavaScript-rendered components in the same Storybook instance. +See [Component Authoring](docs/component-authoring.md) for Twig, React, mixed Storybook, and shared Sass examples. -### Quick Links +## Basic Usage -- [Emulsify Homepage](https://www.emulsify.info/) +Installation and project scripts are usually provided by a starter or platform integration. Manual setup starts with: -## Demo +```sh +npm install @emulsify/core +``` -1. [Storybook](http://storybook.emulsify.info/) +Every project should provide a `project.emulsify.json` file at the project root: -## Contributing +```json +{ + "project": { + "platform": "generic", + "name": "example", + "machineName": "example" + } +} +``` -### [Code of Conduct](https://github.com/emulsify-ds/emulsify-drupal/blob/master/CODE_OF_CONDUCT.md) +Common project scripts call the shared Emulsify Core Vite and Storybook config: -The project maintainers have adopted a Code of Conduct that we expect project participants to adhere to. Please read the full text so that you can understand what actions will and will not be tolerated. +- `storybook`: starts Storybook development. +- `storybook-build`: builds static Storybook output. +- `build`: runs the Vite build for JS, CSS, copied Twig templates, component metadata, and static component assets. +- `lint`: lints maintained project source. -### Contribution Guide +## Documentation -Please also follow the issue template and pull request templates provided. See below for the correct places to post issues: +The documentation is split by task: -1. [Emulsify Drupal](https://github.com/emulsify-ds/emulsify-drupal/issues) -2. [Emulsify Twig Extensions](https://github.com/emulsify-ds/emulsify-twig-extensions/issues) -3. [Emulsify Tools (Drupal module)](https://www.drupal.org/project/issues/emulsify_tools) +| Topic | Use This When | +| --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| [Version Evolution](docs/version-evolution.md) | Understanding how Emulsify Core has evolved across major releases. | +| [Component Authoring](docs/component-authoring.md) | Choosing Twig, React, or mixed Storybook authoring and comparing component examples. | +| [Storybook](docs/storybook.md) | Rendering Twig stories, using `renderTwig()`, understanding Twig runtime helpers, and mixing Twig with React stories. | +| [Project Structure And Output](docs/project-structure.md) | Configuring `src/components`, root `./components`, `variant.structureImplementations`, and expected output paths. | +| [Platform Adapters](docs/platform-adapters.md) | Understanding `generic`, `drupal`, platform resolution order, and Drupal SDC behavior. | +| [Extension Points](docs/extension-points.md) | Adding Vite plugins, Tailwind CSS, Storybook preview overrides, and other framework tooling. | +| [Performance](docs/performance.md) | Understanding sourcemaps, eager Twig imports, Tailwind scanning, copied files, and fixture validation. | +| [Native Twig Extensions](docs/native-twig-extensions.md) | Using `bem()`, `add_attributes()`, and `switch/case/default/endswitch` in Twig.js. | +| [Migration](docs/migration-4x.md) | Upgrading from earlier versions while preserving existing structures. | -### Committing Changes +## Known Limitations -To facilitate automatic semantic release versioning, we utilize the [Conventional Changelog](https://github.com/conventional-changelog/conventional-changelog) standard through Commitizen. Follow these steps when commiting your work to ensure semantic release can version correctly. +- Implemented platform adapters are currently `generic` and `drupal`. WordPress + Timber and Craft CMS are supported as Twig-oriented use cases through the generic adapter today; dedicated adapters are future opportunities. See [Platform Adapters](docs/platform-adapters.md). +- Storybook's Twig resolver eagerly imports Twig modules and raw Twig source. This is reliable for `include()` and `source()`, but large Twig libraries should keep Storybook source roots intentional. See [Performance](docs/performance.md). +- Production sourcemaps are enabled by default unless a project overrides Vite config through `config/emulsify-core/vite/plugins.*`. See [Performance](docs/performance.md). +- Project extensions use the public `config/emulsify-core` directory: `config/emulsify-core/vite/plugins.*` for Vite, `config/emulsify-core/storybook/...` for Storybook, and `config/emulsify-core/a11y.config.js` for a11y. See [Extension Points](docs/extension-points.md). +- Webpack-specific customizations must be migrated manually to Vite plugins or `extendConfig()`. See [Migration](docs/migration-4x.md). +- Drupal SDC mirroring only applies when the Drupal adapter and SDC settings are enabled. Generic projects should expect output to remain in `dist/`. See [Platform Adapters](docs/platform-adapters.md). -1. Stage your changes, ensuring they encompass exactly what you wish to change, no more. -2. Run the `commit` script via `yarn commit` or `npm run commit` and follow the prompts to craft the perfect commit message. -3. Your commit message will be used to create the changelog for the next version that includes that commit. +## Supported Project Shapes -## Author +Release-readiness coverage validates: -Emulsify® is a product of [Four Kitchens](https://fourkitchens.com). +- Drupal SDC projects using `src/components`. +- Generic Twig projects using `src/components`. +- Root `./components` projects. +- Projects using multiple `variant.structureImplementations`. +- Mixed Twig + React Storybook projects. -## Contributors +WordPress + Timber and Craft CMS are Twig-based project use cases that can use the `generic` adapter today. Dedicated adapters for those platforms are future opportunities. The implemented adapters in this package are currently `generic` and `drupal`. - - - - - - - - - - - - -
Callin Mullaney
Callin Mullaney

💻 📖
Randy Oest
Randy Oest

💻 📖
Roberto Hernandez
Roberto Hernandez

💻
Dependabot
Dependabot

🚧
+## Public Imports + +Emulsify Core exposes stable public package paths: + +```js +import { renderTwig } from '@emulsify/core/storybook'; +import { registerTwigExtensions } from '@emulsify/core/extensions/twig'; +import { defineReactExtension } from '@emulsify/core/extensions/react'; +``` + +`defineReactExtension` is reserved for future React extension support. It currently returns the input unchanged. Adopting the import path is safe; the runtime is intentionally a no-op until the registry lands. See [Extension Points](docs/extension-points.md#public-imports). + +Vite consumers can import the shared config from `@emulsify/core/vite` and public Vite plugin helpers from `@emulsify/core/vite/plugins`. + +## Contributing - - +Maintained JavaScript source, config, scripts, and tests should use consistent comments: - +- Start each maintained JS file with a short JSDoc file block that explains the file's responsibility. +- Use JSDoc blocks for exported functions, complex helpers, and public contracts. +- Use `//` comments for local intent, compatibility behavior, and non-obvious edge cases. +- Keep comments concise and factual. Prefer explaining why behavior exists instead of restating the code. +- Use YAML or shell comments in workflow, hook, and fixture files where the format supports comments. -This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! +Do not add comments to JSON files, lockfiles, binary assets, generated output, legal documents, or dependency files. Those formats either do not support comments or should remain exact artifacts. + +Please also follow the issue template and pull request templates provided. See below for the correct places to post issues: + +1. [Emulsify Drupal](https://github.com/emulsify-ds/emulsify-drupal/issues) +2. [Emulsify Tools (Drupal module)](https://www.drupal.org/project/issues/emulsify_tools) + +## Links + +- [Emulsify Homepage](https://www.emulsify.info/) +- [Storybook Demo](http://storybook.emulsify.info/) +- [Code of Conduct](https://github.com/emulsify-ds/emulsify-drupal/blob/master/CODE_OF_CONDUCT.md) + +## Author + +Emulsify® is a product of [Four Kitchens](https://fourkitchens.com). diff --git a/commitlint.config.js b/commitlint.config.js index b387733..2173a5b 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -1,5 +1,10 @@ +/** + * @file Commit message linting configuration. + */ + const Configuration = { - extends: ["@commitlint/config-conventional"], + // Conventional commits feed semantic-release versioning. + extends: ['@commitlint/config-conventional'], }; -export default Configuration; \ No newline at end of file +export default Configuration; diff --git a/config/a11y.config.js b/config/a11y.config.js index 60fb428..77b9fcc 100644 --- a/config/a11y.config.js +++ b/config/a11y.config.js @@ -1,3 +1,10 @@ +/** + * @file Shared accessibility linting configuration. + * + * These defaults are consumed by the pa11y script and can be extended by + * consuming projects through their local Emulsify config. + */ + module.exports = { storybookBuildDir: '../../../../.out', pa11y: { @@ -5,10 +12,7 @@ module.exports = { includeWarnings: false, runners: ['axe'], }, - // A11y linting is done on a component-by-component - // basis, which results in the linter reporting some errors that - // should be ignored. These codes and descriptions allow for those - // errors to be targeted specifically. + // Ignore rules that are noisy for isolated component pages. ignore: { codes: ['landmark-one-main', 'page-has-heading-one'], descriptions: ['Ensures all page content is contained by landmarks'], diff --git a/config/babel.config.js b/config/babel.config.js index 6e040d9..52bd183 100644 --- a/config/babel.config.js +++ b/config/babel.config.js @@ -1,17 +1,12 @@ +/** + * @file Babel configuration for test and legacy transpilation paths. + */ + export default (api) => { api.cache(true); - const presets = [ - [ - 'minify', - { - builtIns: false, - mangle: { - reserved: ['Drupal', 'drupalSettings', 'once'], - }, - }, - ], - ]; + // Disable Babel's generated comments so minified output stays compact. + const presets = [['minify', { builtIns: false }]]; const comments = false; return { presets, comments }; diff --git a/config/eslint.config.js b/config/eslint.config.js index f8aff6b..af2ea66 100644 --- a/config/eslint.config.js +++ b/config/eslint.config.js @@ -1,19 +1,32 @@ -// Import ESLint Flat Config and required plugins +/** + * @file ESLint flat configuration for Emulsify Core. + */ + import js from '@eslint/js'; +import babelParser from '@babel/eslint-parser'; +import importPlugin from 'eslint-plugin-import'; import pluginSecurity from 'eslint-plugin-security'; import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; export default [ - // Base ESLint recommended rules + // Start with core and plugin recommendations before project overrides. js.configs.recommended, - // Plugin configurations + importPlugin.flatConfigs.recommended, pluginSecurity.configs.recommended, eslintPluginPrettierRecommended, { name: 'emulsify-core-config', languageOptions: { + parser: babelParser, + parserOptions: { + requireConfigFile: false, + babelOptions: { + babelrc: false, + configFile: false, + }, + }, sourceType: 'module', ecmaVersion: 'latest', globals: { @@ -28,10 +41,15 @@ export default [ ignores: ['**/*.min.js', '**/node_modules/**/*'], rules: { + // Keep historical project conventions while warning on risky patterns. strict: 0, 'consistent-return': 'off', 'no-underscore-dangle': 'off', 'max-nested-callbacks': ['warn', 3], + 'import/extensions': 'off', + 'import/no-unresolved': 'off', + 'import/no-extraneous-dependencies': 'warn', + 'import/no-mutable-exports': 'warn', 'no-plusplus': ['warn', { allowForLoopAfterthoughts: true }], 'no-param-reassign': 'off', 'no-prototype-builtins': 'off', @@ -45,5 +63,15 @@ export default [ ], quotes: ['error', 'single'], }, + + settings: { + 'import/ignore': ['\\.(scss|less|css)$'], + 'import/resolver': { + node: { + extensions: ['.js', '.jsx'], + moduleDirectory: ['src', 'node_modules'], + }, + }, + }, }, ]; diff --git a/config/jest.config.js b/config/jest.config.js index a38257d..a21a173 100644 --- a/config/jest.config.js +++ b/config/jest.config.js @@ -1,8 +1,27 @@ -module.exports = { +/** + * @file Jest configuration for unit tests and coverage reporting. + */ + +export default { + rootDir: '..', testEnvironment: 'jsdom', + transform: { + '^.+\\.m?js$': [ + 'babel-jest', + { + babelrc: false, + configFile: false, + presets: [['@babel/preset-env', { targets: { node: 'current' } }]], + }, + ], + }, + moduleNameMapper: { + '^virtual:emulsify-twig-globs$': + '/config/vite/test-utils/virtual-twig-globs.js', + }, coverageDirectory: '.coverage', - // @TODO: once every file has 100% test coverage, - // these thresholds should be updated. + coverageProvider: 'v8', + // TODO: Raise these thresholds once coverage exists for every maintained file. coverageThreshold: { global: { branches: 0, diff --git a/config/package-exports.test.js b/config/package-exports.test.js new file mode 100644 index 0000000..6321073 --- /dev/null +++ b/config/package-exports.test.js @@ -0,0 +1,70 @@ +/** + * @file Smoke tests for the package public exports map. + */ + +import { execFileSync } from 'node:child_process'; + +describe('@emulsify/core package exports', () => { + it('imports each public export with native Node ESM resolution', () => { + const checks = [ + ['@emulsify/core', ['react', 'twig']], + ['@emulsify/core/extensions', ['react', 'twig']], + [ + '@emulsify/core/extensions/twig', + ['getTwigFunctionMap', 'registerTwigExtensions'], + ], + [ + '@emulsify/core/extensions/react', + ['createReactExtensionRegistry', 'defineReactExtension'], + ], + [ + '@emulsify/core/storybook', + ['renderHtmlStoryResult', 'renderTwig', 'TwigHtmlStory', 'TwigStory'], + ], + ['@emulsify/core/vite', ['default']], + [ + '@emulsify/core/vite/plugins', + ['makePlugins', 'makeTwigNamespaces', 'makeTwigPluginOptions'], + ], + ]; + const script = ` + const checks = ${JSON.stringify(checks)}; + for (const [specifier, expectedExports] of checks) { + const module = await import(specifier); + for (const exportName of expectedExports) { + if (module[exportName] === undefined) { + throw new Error(\`Missing \${exportName} from \${specifier}\`); + } + } + } + const { renderTwig } = await import('@emulsify/core/storybook'); + if (typeof renderTwig !== 'function') { + throw new Error('renderTwig is not a function'); + } + try { + await import('@emulsify/core/config/vite/project-config.js'); + throw new Error('Internal project-config import unexpectedly succeeded'); + } catch (error) { + if (error?.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') { + throw error; + } + } + `; + + expect(() => { + execFileSync(process.execPath, ['--input-type=module', '--eval', script]); + }).not.toThrow(); + }); + + it('exposes renderTwig from the Storybook public entry', async () => { + const { renderTwig } = await import('@emulsify/core/storybook'); + + expect(typeof renderTwig).toBe('function'); + }); + + it('does not expose internal implementation subpaths to Jest resolution', async () => { + await expect( + import('@emulsify/core/config/vite/project-config.js'), + ).rejects.toThrow(); + }); +}); diff --git a/config/postcss.config.js b/config/postcss.config.js index 2b5384e..86807a8 100644 --- a/config/postcss.config.js +++ b/config/postcss.config.js @@ -1,5 +1,10 @@ +/** + * @file PostCSS plugin configuration. + */ + import autoPrefixer from 'autoprefixer'; export default { + // Autoprefixer keeps compiled CSS compatible with supported browsers. plugins: [autoPrefixer()], }; diff --git a/config/vite/entries.js b/config/vite/entries.js new file mode 100644 index 0000000..4afb42a --- /dev/null +++ b/config/vite/entries.js @@ -0,0 +1,253 @@ +/** + * @file Entries map builder for Vite/Rollup. + * + * Builds a keyed input map (for `build.rollupOptions.input`) where the map key + * encodes the final folder inside the Vite outDir (default `dist/`). + * + * Modern projects: + * - Global/base assets -> "global/..." + * - Component assets -> "components/..." (or mirrored to ./components when Drupal) + * - SDC=true removes the injected "/css" or "/js" bucket + * + * Component Structure Overrides projects (project.emulsify.json: variant.structureImplementations): + * - Only compile JS/SCSS. + * - JS -> "js/" + * - CSS -> "css/" + * - Twig/assets copying is handled by plugins using the same structure model. + * - cl-* / sb-* SCSS -> "storybook/" + */ + +import fs from 'fs'; +import { resolve } from 'path'; +import { globSync } from 'glob'; +import { + compiledAssetOutputPath, + resolveProjectStructure, + storybookStyleOutputPath, +} from './project-structure.js'; +import { replaceLastSlash, toPosix } from './utils/paths.js'; +import { unique } from './utils/unique.js'; + +export { replaceLastSlash, toPosix }; + +/** Remove characters that would confuse Rollup naming or file systems. */ +export const sanitizePath = (s) => s.replace(/[^a-zA-Z0-9/_-]/g, ''); + +/** + * @typedef {Object} BuildContext + * @property {string} projectDir + * @property {string} srcDir + * @property {boolean} srcExists + * @property {boolean} isDrupal - kept for downstream logic parity + * @property {boolean} SDC + * @property {boolean} structureOverrides + * @property {string[]} [structureRoots] + */ + +/* -------------------------------------------------------------------------- */ +/* Utilities */ +/* -------------------------------------------------------------------------- */ + +/** + * Safe map setter that avoids prototype pollution keys. + * @param {Record} map + * @param {string} key + * @param {string} value + */ +function safeSetKey(map, key, value) { + const forbidden = ['__proto__', 'prototype', 'constructor']; + if (!key || forbidden.some((bad) => key.includes(bad))) return; + map[key] = value; // eslint-disable-line security/detect-object-injection +} + +/** + * Glob a pattern below each source root. + * + * @param {{directory: string}[]} roots - Source root records. + * @param {string} pattern - Glob pattern relative to each root. + * @param {object} [options={}] - Glob options. + * @returns {string[]} Matching files. + */ +function globFromRoots(roots, pattern, options = {}) { + return unique( + roots + .flatMap((root) => + globSync(toPosix(resolve(root.directory, pattern)), options), + ) + .filter(Boolean), + ); +} + +/** + * Build ignored global paths for a global source root. + * + * @param {string} rootDir - Absolute global source root. + * @returns {string[]} Ignore globs. + */ +function globalIgnorePatterns(rootDir) { + return [ + toPosix(resolve(rootDir, 'components/**')), + toPosix(resolve(rootDir, 'util/**')), + ]; +} + +/* -------------------------------------------------------------------------- */ +/* Inputs builder */ +/* -------------------------------------------------------------------------- */ + +/** + * Build the Rollup/Vite input map. + * + * Keys are paths **relative to outDir**, without extensions. Examples: + * - "global/layout/css/layout" + * - "components/accordion/js/accordion" (or without "/js" when SDC=true) + * + * For Component Structure Overrides (variant.structureImplementations present), + * only JS/CSS keys are produced under "js/**" and "css/**". + * + * @param {BuildContext} ctx + * @returns {Record} + */ +export function buildInputs(ctx) { + const structure = ctx.projectStructure || resolveProjectStructure(ctx); + + /** @type {Record} */ + const inputs = {}; + + /** + * Add a key/file pair into the inputs map safely (sanitized + POSIX). + * @param {string|null} key + * @param {string} abs + */ + const add = (key, abs) => { + if (!key) return; + const clean = sanitizePath(toPosix(key)).replace(/^\/+/, ''); + if (!clean) return; + safeSetKey(inputs, clean, abs); + }; + + /* ------------------------------------------------------------------------ */ + /* STRUCTURE OVERRIDES BRANCH */ + /* ------------------------------------------------------------------------ */ + if (structure.structureOverrides) { + // Gather *.js and *.scss from each declared variant root directory. + const jsFiles = globFromRoots( + structure.componentRootRecords, + '**/!(*.stories|*.component|*.min|*.test).js', + ); + const scssFiles = globFromRoots( + structure.componentRootRecords, + '**/!(_*|cl-*|sb-*).scss', + ); + const storybookScss = globFromRoots( + structure.componentRootRecords, + '**/*{cl-*,sb-*}.scss', + ); + + // JS files emit under dist/js using the path below components when possible. + for (const file of jsFiles) { + add(compiledAssetOutputPath(file, 'js', structure, ctx), file); + } + + // SCSS files emit under dist/css using the same relative path rules. + for (const file of scssFiles) { + add(compiledAssetOutputPath(file, 'css', structure, ctx), file); + } + + // Storybook and component-library styles stay under dist/storybook. + for (const file of storybookScss) { + add(storybookStyleOutputPath(file, structure, ctx), file); + } + + return inputs; + } + + /* ------------------------------------------------------------------------ */ + /* MODERN BRANCH (existing behavior preserved) */ + /* ------------------------------------------------------------------------ */ + // Global JS + for (const globalRoot of structure.globalRootRecords) { + const files = globSync( + toPosix( + resolve( + globalRoot.directory, + '!(components|util)/**/!(*.stories|*.component|*.min|*.test).js', + ), + ), + { ignore: globalIgnorePatterns(globalRoot.directory) }, + ); + for (const file of files) { + add(compiledAssetOutputPath(file, 'js', structure, ctx), file); + } + } + + // Component JS + for (const file of globFromRoots( + structure.componentRootRecords, + '**/!(*.stories|*.component|*.min|*.test).js', + )) { + add(compiledAssetOutputPath(file, 'js', structure, ctx), file); + } + + // Global SCSS + for (const globalRoot of structure.globalRootRecords) { + const files = globSync( + toPosix( + resolve( + globalRoot.directory, + '!(components|util)/**/!(_*|cl-*|sb-*).scss', + ), + ), + { ignore: globalIgnorePatterns(globalRoot.directory) }, + ); + for (const file of files) { + add(compiledAssetOutputPath(file, 'css', structure, ctx), file); + } + } + + // Component SCSS + for (const file of globFromRoots( + structure.componentRootRecords, + '**/!(_*|cl-*|sb-*).scss', + )) { + add(compiledAssetOutputPath(file, 'css', structure, ctx), file); + } + + // Storybook/CL SCSS + for (const file of globFromRoots( + structure.sourceRootRecords, + '**/*{cl-*,sb-*}.scss', + )) { + add(storybookStyleOutputPath(file, structure, ctx), file); + } + + return inputs; +} + +/** + * Convenience wrapper that infers `srcDir` and returns an inputs map. + * @param {string} projectDir + * @param {boolean} [isDrupal=false] + * @param {boolean} [SDC=false] + * @returns {Record} + */ +export function buildInputsFromProject( + projectDir, + isDrupal = false, + SDC = false, +) { + const srcPath = resolve(projectDir, 'src'); + const srcExists = fs.existsSync(srcPath); + const srcDir = srcExists ? srcPath : resolve(projectDir, 'components'); + + const ctx = { + projectDir, + srcDir, + srcExists, + isDrupal, + SDC, + structureOverrides: false, + structureRoots: [], + }; + return buildInputs(ctx); +} diff --git a/config/vite/entries.test.js b/config/vite/entries.test.js new file mode 100644 index 0000000..c8792b1 --- /dev/null +++ b/config/vite/entries.test.js @@ -0,0 +1,148 @@ +/** + * @file Tests for Vite/Rollup entry key generation. + */ + +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'fs'; +import { dirname, join, relative } from 'path'; +import { tmpdir } from 'os'; +import { buildInputs } from './entries.js'; +import { resolveProjectConfig } from './project-config.js'; +import { toPosixPath } from './utils/paths.js'; + +const makeTempProject = () => mkdtempSync(join(tmpdir(), 'emulsify-core-')); + +const writeProjectConfig = (projectDir, config) => { + writeFileSync( + join(projectDir, 'project.emulsify.json'), + JSON.stringify(config, null, 2), + ); +}; + +const writeSourceFile = (projectDir, relPath, contents = '') => { + const absPath = join(projectDir, relPath); + mkdirSync(dirname(absPath), { recursive: true }); + writeFileSync(absPath, contents); +}; + +const buildRelativeInputs = (projectDir) => { + const env = resolveProjectConfig(projectDir, {}); + const inputs = buildInputs(env); + + return Object.fromEntries( + Object.entries(inputs) + .sort(([a], [b]) => a.localeCompare(b)) + .map(([key, value]) => [key, toPosixPath(relative(projectDir, value))]), + ); +}; + +describe('buildInputs structure outputs', () => { + let projectDir; + + afterEach(() => { + if (projectDir) { + rmSync(projectDir, { recursive: true, force: true }); + } + }); + + it('preserves Drupal SDC output for src/components projects', () => { + projectDir = makeTempProject(); + writeProjectConfig(projectDir, { + project: { + platform: 'drupal', + singleDirectoryComponents: true, + }, + }); + writeSourceFile(projectDir, 'src/components/card/card.js'); + writeSourceFile(projectDir, 'src/components/card/card.scss'); + + expect(buildRelativeInputs(projectDir)).toMatchInlineSnapshot(` +{ + "components/card/card": "src/components/card/card.js", + "components/card/card__style": "src/components/card/card.scss", +} +`); + }); + + it('preserves generic output for src/components projects', () => { + projectDir = makeTempProject(); + writeProjectConfig(projectDir, { + project: { + platform: 'generic', + }, + }); + writeSourceFile(projectDir, 'src/base/base.js'); + writeSourceFile(projectDir, 'src/base/base.scss'); + writeSourceFile(projectDir, 'src/components/card/card.js'); + writeSourceFile(projectDir, 'src/components/card/card.scss'); + writeSourceFile(projectDir, 'src/components/card/_partial.scss'); + writeSourceFile(projectDir, 'src/components/card/card.stories.js'); + writeSourceFile(projectDir, 'src/components/card/card.component.js'); + writeSourceFile(projectDir, 'src/components/card/card.min.js'); + writeSourceFile(projectDir, 'src/components/card/card.test.js'); + writeSourceFile(projectDir, 'src/components/card/cl-card.scss'); + + expect(buildRelativeInputs(projectDir)).toMatchInlineSnapshot(` +{ + "components/card/css/card": "src/components/card/card.scss", + "components/card/js/card": "src/components/card/card.js", + "global/base/css/base": "src/base/base.scss", + "global/base/js/base": "src/base/base.js", + "storybook/components/card/cl-card": "src/components/card/cl-card.scss", +} +`); + }); + + it('supports canonical root components-only projects', () => { + projectDir = makeTempProject(); + writeProjectConfig(projectDir, { + project: { + platform: 'generic', + }, + }); + writeSourceFile(projectDir, 'components/card/card.js'); + writeSourceFile(projectDir, 'components/card/card.scss'); + writeSourceFile(projectDir, 'components/card/sb-card.scss'); + + expect(buildRelativeInputs(projectDir)).toMatchInlineSnapshot(` +{ + "components/card/css/card": "components/card/card.scss", + "components/card/js/card": "components/card/card.js", + "storybook/card/sb-card": "components/card/sb-card.scss", +} +`); + }); + + it('preserves structureImplementation entry output paths', () => { + projectDir = makeTempProject(); + writeProjectConfig(projectDir, { + project: { + platform: 'drupal', + }, + variant: { + structureImplementations: [ + { name: 'components', directory: './src/components/' }, + { name: 'foundation', directory: './src/foundation/' }, + { name: 'layout', directory: './src/layout/' }, + { name: 'tokens', directory: './src/tokens/' }, + ], + }, + }); + writeSourceFile(projectDir, 'src/components/button/button.js'); + writeSourceFile(projectDir, 'src/components/button/button.scss'); + writeSourceFile(projectDir, 'src/components/button/cl-button.scss'); + writeSourceFile(projectDir, 'src/foundation/colors/colors.js'); + writeSourceFile(projectDir, 'src/foundation/colors/colors.scss'); + writeSourceFile(projectDir, 'src/layout/grid/sb-grid.scss'); + + expect(buildRelativeInputs(projectDir)).toMatchInlineSnapshot(` +{ + "css/button/button": "src/components/button/button.scss", + "css/src/foundation/colors/colors": "src/foundation/colors/colors.scss", + "js/button/button": "src/components/button/button.js", + "js/src/foundation/colors/colors": "src/foundation/colors/colors.js", + "storybook/src/components/button/cl-button": "src/components/button/cl-button.scss", + "storybook/src/layout/grid/sb-grid": "src/layout/grid/sb-grid.scss", +} +`); + }); +}); diff --git a/config/vite/environment.js b/config/vite/environment.js new file mode 100644 index 0000000..7c05d11 --- /dev/null +++ b/config/vite/environment.js @@ -0,0 +1,39 @@ +/** + * @file Environment resolution for Emulsify + Vite. + * + * Reads project settings and exposes a normalized "env" object used by + * entries, plugins, and the Vite config. + * + * Highlights: + * - `platform`: from env var or project.emulsify.json (default "generic"). + * - `SDC`: boolean from project.emulsify.json `project.singleDirectoryComponents`. + * - `structureOverrides`: true when safe `variant.structureImplementations` exist. + * - `structureRoots`: array of directories from `variant.structureImplementations`. + * - `platformAdapter`: active adapter for platform-specific behavior. + */ + +import { resolveProjectConfig } from './project-config.js'; + +/** + * Resolve environment details for the current project. + * + * @returns {{ + * projectDir: string, + * srcDir: string, + * srcExists: boolean, + * platform: 'drupal' | 'generic' | string, + * SDC: boolean, + * structureOverrides: boolean, + * structureRoots: string[], + * structureImplementations: Array<{name: string, directory: string}>, + * componentRoots: string[], + * globalRoots: string[], + * namespaceRoots: Record, + * outputStrategy: string, + * projectStructure: object, + * platformAdapter: object + * }} + */ +export function resolveEnvironment() { + return resolveProjectConfig(process.cwd(), process.env); +} diff --git a/config/vite/platforms.js b/config/vite/platforms.js new file mode 100644 index 0000000..849cf4d --- /dev/null +++ b/config/vite/platforms.js @@ -0,0 +1,68 @@ +/** + * @file Platform adapter definitions for Emulsify project behavior. + * + * Adapters expose platform-specific defaults as serializable data so the same + * decisions can be used by Node-side Vite config and Storybook browser code. + */ + +const genericAdapter = { + name: 'generic', + outputStrategy: 'dist', + storybook: { + loadDrupalBehaviorShim: false, + attachDrupalBehaviors: false, + registerDrupalTwigFilters: false, + loadMirroredComponentCss: false, + }, + build: { + mirrorDistComponentsToRoot: false, + }, +}; + +const drupalAdapter = { + name: 'drupal', + outputStrategy: 'drupal-sdc', + storybook: { + loadDrupalBehaviorShim: true, + attachDrupalBehaviors: true, + registerDrupalTwigFilters: true, + loadMirroredComponentCss: true, + }, + build: { + mirrorDistComponentsToRoot: true, + }, +}; + +const adapters = { + generic: genericAdapter, + drupal: drupalAdapter, +}; + +/** + * Deep-clone an adapter so callers can safely serialize or extend it. + * + * @param {object} adapter - Adapter definition. + * @returns {object} Adapter clone. + */ +function cloneAdapter(adapter) { + return JSON.parse(JSON.stringify(adapter)); +} + +/** + * Resolve the platform adapter for a normalized platform name. + * + * Unknown platforms intentionally use generic behavior while preserving the + * resolved `platform` string separately on the environment object. + * + * @param {string} [platform='generic'] - Normalized platform name. + * @returns {object} Serializable platform adapter. + */ +export function getPlatformAdapter(platform = 'generic') { + const key = (platform || 'generic').toString().toLowerCase().trim(); + if (key === 'drupal') { + return cloneAdapter(drupalAdapter); + } + return cloneAdapter(genericAdapter); +} + +export { adapters }; diff --git a/config/vite/plugins.js b/config/vite/plugins.js new file mode 100644 index 0000000..f5cf0f9 --- /dev/null +++ b/config/vite/plugins.js @@ -0,0 +1,12 @@ +/** + * @file Public barrel for Emulsify Vite plugin helpers. + * + * This file preserves the `@emulsify/core/vite/plugins` export path while the + * implementation lives in focused internal modules under `config/vite/plugins/`. + */ + +export { makePlugins } from './plugins/index.js'; +export { + makeTwigNamespaces, + makeTwigPluginOptions, +} from './plugins/twig-module.js'; diff --git a/config/vite/plugins.test.js b/config/vite/plugins.test.js new file mode 100644 index 0000000..2aa4b14 --- /dev/null +++ b/config/vite/plugins.test.js @@ -0,0 +1,115 @@ +/** + * @file Integration tests for the public Vite plugins barrel. + */ + +import { existsSync, mkdirSync, rmSync, writeFileSync } from 'fs'; +import { join } from 'path'; + +import * as pluginsModule from './plugins.js'; +import { makeEnv, makeTempProject, pluginNames } from './test-utils/plugins.js'; + +jest.mock('vite-plugin-sass-glob-import', () => ({ + __esModule: true, + default: jest.fn(() => ({ name: 'vite-plugin-sass-glob-import' })), +})); +jest.mock('@vituum/vite-plugin-twig', () => ({ + __esModule: true, + default: jest.fn(() => [ + { + name: '@vituum/vite-plugin-twig', + buildStart: jest.fn(), + buildEnd: jest.fn(), + }, + { name: '@vituum/vite-plugin-core:bundle' }, + ]), +})); + +describe('Vite plugin public barrel', () => { + let projectDir; + + afterEach(() => { + if (projectDir) { + rmSync(projectDir, { recursive: true, force: true }); + } + }); + + it('preserves the public export list', () => { + expect(Object.keys(pluginsModule).sort()).toEqual([ + 'makePlugins', + 'makeTwigNamespaces', + 'makeTwigPluginOptions', + ]); + }); + + it('composes the Emulsify plugin chain end-to-end', () => { + projectDir = makeTempProject(); + mkdirSync(join(projectDir, 'src/components'), { recursive: true }); + + const names = pluginNames(pluginsModule.makePlugins(makeEnv(projectDir))); + + expect(names).toEqual( + expect.arrayContaining([ + 'emulsify-twig-module', + '@vituum/vite-plugin-twig', + 'emulsify-svg-sprite-file', + 'vite-plugin-sass-glob-import', + 'emulsify-yaml', + 'emulsify-css-asset-url-relativizer', + 'emulsify-copy-twig-files', + 'emulsify-copy-all-src-assets', + 'emulsify-mirror-components-to-root', + ]), + ); + expect(names).not.toContain('@vituum/vite-plugin-core:bundle'); + }); + + it('only enables root component mirroring for Drupal projects with src', () => { + projectDir = makeTempProject(); + const distComponentFile = join( + projectDir, + 'dist/components/card/card.twig', + ); + const rootComponentFile = join(projectDir, 'components/card/card.twig'); + + const genericMirror = pluginsModule + .makePlugins(makeEnv(projectDir)) + .find((plugin) => plugin?.name === 'emulsify-mirror-components-to-root'); + const drupalMirror = pluginsModule + .makePlugins(makeEnv(projectDir, { platform: 'drupal' })) + .find((plugin) => plugin?.name === 'emulsify-mirror-components-to-root'); + const legacyDrupalMirror = pluginsModule + .makePlugins( + makeEnv(projectDir, { + platform: 'drupal', + srcExists: false, + }), + ) + .find((plugin) => plugin?.name === 'emulsify-mirror-components-to-root'); + + mkdirSync(join(projectDir, 'dist/components/card'), { recursive: true }); + writeFileSync(distComponentFile, '
{{ title }}
'); + genericMirror.configResolved({ + build: { outDir: join(projectDir, 'dist') }, + }); + expect(genericMirror.writeBundle()).toBeUndefined(); + expect(existsSync(distComponentFile)).toBe(true); + expect(existsSync(rootComponentFile)).toBe(false); + + drupalMirror.configResolved({ + build: { outDir: join(projectDir, 'dist') }, + }); + expect(drupalMirror.writeBundle()).toBeUndefined(); + expect(existsSync(distComponentFile)).toBe(false); + expect(existsSync(rootComponentFile)).toBe(true); + + rmSync(join(projectDir, 'components'), { recursive: true, force: true }); + mkdirSync(join(projectDir, 'dist/components/card'), { recursive: true }); + writeFileSync(distComponentFile, '
{{ title }}
'); + legacyDrupalMirror.configResolved({ + build: { outDir: join(projectDir, 'dist') }, + }); + expect(legacyDrupalMirror.writeBundle()).toBeUndefined(); + expect(existsSync(distComponentFile)).toBe(true); + expect(existsSync(rootComponentFile)).toBe(false); + }); +}); diff --git a/config/vite/plugins/__tests__/copy-files.test.js b/config/vite/plugins/__tests__/copy-files.test.js new file mode 100644 index 0000000..1b2a236 --- /dev/null +++ b/config/vite/plugins/__tests__/copy-files.test.js @@ -0,0 +1,130 @@ +/** + * @file Tests for source Twig, metadata, and static asset copy plugins. + */ + +import { existsSync, mkdirSync, rmSync, writeFileSync } from 'fs'; +import { join } from 'path'; + +import { resolveProjectConfig } from '../../project-config.js'; +import { resolveProjectStructure } from '../../project-structure.js'; +import { copyAllSrcAssetsPlugin } from '../copy-src-assets.js'; +import { copyTwigFilesPlugin } from '../copy-twig-files.js'; +import { + makeEnv, + makeTempProject, + writeProjectConfig, +} from '../../test-utils/plugins.js'; + +describe('source copy plugins', () => { + let projectDir; + + afterEach(() => { + if (projectDir) { + rmSync(projectDir, { recursive: true, force: true }); + } + }); + + const runCopyPlugins = (structure, outDir) => { + const copyTwigPlugin = copyTwigFilesPlugin({ structure }); + const copyAssetsPlugin = copyAllSrcAssetsPlugin({ structure }); + + copyTwigPlugin.configResolved({ build: { outDir } }); + copyAssetsPlugin.configResolved({ build: { outDir } }); + copyTwigPlugin.writeBundle(); + copyAssetsPlugin.writeBundle(); + }; + + it('copies static assets from root component directories to dist/components', () => { + projectDir = makeTempProject(); + const componentDir = join(projectDir, 'components/card'); + const outDir = join(projectDir, 'dist'); + mkdirSync(componentDir, { recursive: true }); + writeFileSync(join(componentDir, 'card.twig'), '
'); + writeFileSync(join(componentDir, '_partial.twig'), ''); + writeFileSync(join(componentDir, 'card.component.yml'), 'name: Card'); + writeFileSync(join(componentDir, 'image.png'), 'image'); + writeFileSync(join(componentDir, 'card.js'), 'console.log("skip");'); + writeFileSync(join(componentDir, 'card.scss'), '.skip {}'); + + const structure = resolveProjectStructure( + makeEnv(projectDir, { + srcDir: join(projectDir, 'components'), + srcExists: false, + }), + ); + + runCopyPlugins(structure, outDir); + + expect(existsSync(join(outDir, 'components/card/card.twig'))).toBe(true); + expect(existsSync(join(outDir, 'components/card/_partial.twig'))).toBe( + false, + ); + expect(existsSync(join(outDir, 'components/card/card.component.yml'))).toBe( + true, + ); + expect(existsSync(join(outDir, 'components/card/image.png'))).toBe(true); + expect(existsSync(join(outDir, 'components/card/card.js'))).toBe(false); + expect(existsSync(join(outDir, 'components/card/card.scss'))).toBe(false); + }); + + it('copies assets from named structure roots to matching dist folders', () => { + projectDir = makeTempProject(); + const outDir = join(projectDir, 'dist'); + writeProjectConfig(projectDir, { + project: { + platform: 'generic', + }, + variant: { + structureImplementations: [ + { name: 'components', directory: './src/components/' }, + { name: 'foundation', directory: './src/foundation/' }, + ], + }, + }); + mkdirSync(join(projectDir, 'src/components/card'), { recursive: true }); + mkdirSync(join(projectDir, 'src/foundation/icons'), { recursive: true }); + writeFileSync( + join(projectDir, 'src/components/card/card.twig'), + '
', + ); + writeFileSync( + join(projectDir, 'src/components/card/_partial.twig'), + '', + ); + writeFileSync( + join(projectDir, 'src/components/card/card.component.yml'), + 'name: Card', + ); + writeFileSync(join(projectDir, 'src/components/card/image.png'), 'image'); + writeFileSync(join(projectDir, 'src/foundation/icons/icon.svg'), ''); + writeFileSync( + join(projectDir, 'src/foundation/icons/_partial.twig'), + '', + ); + writeFileSync( + join(projectDir, 'src/foundation/icons/icon.component.json'), + '{"name":"Icon"}', + ); + + runCopyPlugins( + resolveProjectConfig(projectDir, {}).projectStructure, + outDir, + ); + + expect(existsSync(join(outDir, 'components/card/card.twig'))).toBe(true); + expect(existsSync(join(outDir, 'components/card/_partial.twig'))).toBe( + false, + ); + expect(existsSync(join(outDir, 'components/card/card.component.yml'))).toBe( + true, + ); + expect(existsSync(join(outDir, 'components/card/image.png'))).toBe(true); + expect(existsSync(join(outDir, 'foundation/icons/icon.svg'))).toBe(true); + expect(existsSync(join(outDir, 'foundation/icons/_partial.twig'))).toBe( + false, + ); + expect( + existsSync(join(outDir, 'foundation/icons/icon.component.json')), + ).toBe(true); + }); +}); diff --git a/config/vite/plugins/__tests__/mirror-components.test.js b/config/vite/plugins/__tests__/mirror-components.test.js new file mode 100644 index 0000000..afbb84f --- /dev/null +++ b/config/vite/plugins/__tests__/mirror-components.test.js @@ -0,0 +1,161 @@ +/** + * @file Tests for Drupal component mirror plugin behavior. + */ + +import { + existsSync, + mkdirSync, + readFileSync, + rmSync, + statSync, + utimesSync, + writeFileSync, +} from 'fs'; +import { join } from 'path'; + +import { mirrorComponentsToRoot } from '../mirror-components.js'; +import { makeTempProject } from '../../test-utils/plugins.js'; + +const MIRROR_STATE_FILE = '.emulsify-mirror-state.json'; + +const readMirrorState = (outDir) => + JSON.parse(readFileSync(join(outDir, MIRROR_STATE_FILE), 'utf8')); + +describe('component mirror plugin', () => { + let projectDir; + + afterEach(() => { + if (projectDir) { + rmSync(projectDir, { recursive: true, force: true }); + } + }); + + it('mirrors built components when enabled and skips mirroring when disabled', () => { + projectDir = makeTempProject(); + const outDir = join(projectDir, 'dist'); + const distComponentFile = join(outDir, 'components/card/card.twig'); + const rootComponentFile = join(projectDir, 'components/card/card.twig'); + const disabledMirror = mirrorComponentsToRoot({ + enabled: false, + projectDir, + }); + const enabledMirror = mirrorComponentsToRoot({ + enabled: true, + projectDir, + }); + + mkdirSync(join(outDir, 'components/card'), { recursive: true }); + writeFileSync(distComponentFile, '
{{ title }}
'); + disabledMirror.configResolved({ build: { outDir } }); + expect(disabledMirror.writeBundle()).toBeUndefined(); + expect(existsSync(distComponentFile)).toBe(true); + expect(existsSync(rootComponentFile)).toBe(false); + + enabledMirror.configResolved({ build: { outDir } }); + expect(enabledMirror.writeBundle()).toBeUndefined(); + expect(existsSync(distComponentFile)).toBe(false); + expect(existsSync(rootComponentFile)).toBe(true); + expect(readMirrorState(outDir).completedAt).toEqual(expect.any(String)); + }); + + it('does not rewrite identical mirrored component files', () => { + projectDir = makeTempProject(); + const outDir = join(projectDir, 'dist'); + const distComponentFile = join(outDir, 'components/card/card.twig'); + const rootComponentFile = join(projectDir, 'components/card/card.twig'); + const mirror = mirrorComponentsToRoot({ enabled: true, projectDir }); + + mkdirSync(join(outDir, 'components/card'), { recursive: true }); + mkdirSync(join(projectDir, 'components/card'), { recursive: true }); + writeFileSync(distComponentFile, '
{{ title }}
'); + writeFileSync(rootComponentFile, '
{{ title }}
'); + utimesSync( + rootComponentFile, + new Date('2000-01-01T00:00:00Z'), + new Date('2000-01-01T00:00:00Z'), + ); + const rootMtimeBefore = statSync(rootComponentFile).mtimeMs; + + mirror.configResolved({ build: { outDir } }); + expect(mirror.writeBundle()).toBeUndefined(); + + expect(existsSync(distComponentFile)).toBe(false); + expect(statSync(rootComponentFile).mtimeMs).toBe(rootMtimeBefore); + }); + + it('keeps interleaved build observations free of partial dist component files', () => { + projectDir = makeTempProject(); + const outDir = join(projectDir, 'dist'); + const fixtureFiles = [ + 'card.js', + 'card.css', + 'card.twig', + 'card.component.yml', + 'card.asset.txt', + ]; + const firstMirror = mirrorComponentsToRoot({ enabled: true, projectDir }); + const secondMirror = mirrorComponentsToRoot({ enabled: true, projectDir }); + const writeDistFixture = (label) => { + mkdirSync(join(outDir, 'components/card'), { recursive: true }); + for (const fileName of fixtureFiles) { + writeFileSync( + join(outDir, 'components/card', fileName), + `${fileName}: ${label}`, + ); + } + }; + const expectMirroredFixture = (label) => { + for (const fileName of fixtureFiles) { + expect(existsSync(join(outDir, 'components/card', fileName))).toBe( + false, + ); + expect( + readFileSync(join(projectDir, 'components/card', fileName), 'utf8'), + ).toBe(`${fileName}: ${label}`); + } + }; + + firstMirror.configResolved({ build: { outDir } }); + secondMirror.configResolved({ build: { outDir } }); + + writeDistFixture('first build'); + expect(firstMirror.writeBundle()).toBeUndefined(); + expectMirroredFixture('first build'); + + writeDistFixture('second build'); + expect(secondMirror.writeBundle()).toBeUndefined(); + expectMirroredFixture('second build'); + expect(readMirrorState(outDir).completedAt).toEqual(expect.any(String)); + }); + + it('warns when a previous mirror build marker was interrupted', () => { + projectDir = makeTempProject(); + const outDir = join(projectDir, 'dist'); + const markerFile = join(outDir, MIRROR_STATE_FILE); + const mirror = mirrorComponentsToRoot({ enabled: true, projectDir }); + const consoleWarn = jest + .spyOn(console, 'warn') + .mockImplementation(() => {}); + + mkdirSync(outDir, { recursive: true }); + writeFileSync( + markerFile, + JSON.stringify({ + startedAt: '2026-05-26T00:00:00.000Z', + completedAt: null, + version: '0.0.0-test', + }), + ); + + mirror.configResolved({ build: { outDir } }); + expect(mirror.writeBundle()).toBeUndefined(); + + expect(consoleWarn).toHaveBeenCalledWith( + expect.stringContaining( + 'Previous Emulsify component mirror build was interrupted', + ), + ); + expect(readMirrorState(outDir).completedAt).toEqual(expect.any(String)); + consoleWarn.mockRestore(); + }); +}); diff --git a/config/vite/plugins/__tests__/twig-module.test.js b/config/vite/plugins/__tests__/twig-module.test.js new file mode 100644 index 0000000..217c1fb --- /dev/null +++ b/config/vite/plugins/__tests__/twig-module.test.js @@ -0,0 +1,216 @@ +/** + * @file Tests for Twig module plugin compilation and namespace behavior. + */ + +import { mkdirSync, rmSync, writeFileSync } from 'fs'; +import { join } from 'path'; + +import { resolveProjectConfig } from '../../project-config.js'; +import { + emulsifyTwigModulePlugin, + makeTwigNamespaces, + makeTwigPluginOptions, +} from '../twig-module.js'; +import { + makeEnv, + makeTempProject, + renderGeneratedTwigModule, + transformTwigModule, + twigEmbed, + twigInclude, + writeProjectConfig, +} from '../../test-utils/plugins.js'; + +describe('Twig module plugin', () => { + let projectDir; + + afterEach(() => { + if (projectDir) { + rmSync(projectDir, { recursive: true, force: true }); + } + }); + + const makeTwigModulePlugin = (env) => + emulsifyTwigModulePlugin(makeTwigPluginOptions(env)); + + it('builds Twig namespaces for src/components projects', () => { + projectDir = makeTempProject(); + mkdirSync(join(projectDir, 'src/components'), { recursive: true }); + mkdirSync(join(projectDir, 'src/layout'), { recursive: true }); + mkdirSync(join(projectDir, 'src/tokens'), { recursive: true }); + + expect(makeTwigNamespaces(makeEnv(projectDir))).toEqual({ + components: join(projectDir, 'src/components'), + layout: join(projectDir, 'src/layout'), + tokens: join(projectDir, 'src/tokens'), + }); + }); + + it('builds Twig namespaces for top-level components projects', () => { + projectDir = makeTempProject(); + mkdirSync(join(projectDir, 'components'), { recursive: true }); + mkdirSync(join(projectDir, 'layout'), { recursive: true }); + mkdirSync(join(projectDir, 'tokens'), { recursive: true }); + + expect( + makeTwigNamespaces( + makeEnv(projectDir, { + srcDir: join(projectDir, 'components'), + srcExists: false, + }), + ), + ).toEqual({ + components: join(projectDir, 'components'), + layout: join(projectDir, 'layout'), + tokens: join(projectDir, 'tokens'), + }); + }); + + it('prefers structure override roots for component namespaces', () => { + projectDir = makeTempProject(); + const overrideRoot = join(projectDir, 'custom/components'); + mkdirSync(overrideRoot, { recursive: true }); + mkdirSync(join(projectDir, 'src/layout'), { recursive: true }); + mkdirSync(join(projectDir, 'src/tokens'), { recursive: true }); + + expect( + makeTwigNamespaces( + makeEnv(projectDir, { + structureOverrides: true, + structureRoots: [overrideRoot], + }), + ), + ).toEqual({ + components: overrideRoot, + }); + }); + + it('builds Twig namespaces for multiple named structure roots', () => { + projectDir = makeTempProject(); + writeProjectConfig(projectDir, { + project: { + platform: 'generic', + }, + variant: { + structureImplementations: [ + { name: 'components', directory: './src/components/' }, + { name: 'foundation', directory: './src/foundation/' }, + { name: 'layout', directory: './src/layout/' }, + { name: 'tokens', directory: './src/tokens/' }, + ], + }, + }); + mkdirSync(join(projectDir, 'src/components'), { recursive: true }); + mkdirSync(join(projectDir, 'src/foundation'), { recursive: true }); + mkdirSync(join(projectDir, 'src/layout'), { recursive: true }); + mkdirSync(join(projectDir, 'src/tokens'), { recursive: true }); + + expect(makeTwigNamespaces(resolveProjectConfig(projectDir, {}))).toEqual({ + components: join(projectDir, 'src/components'), + foundation: join(projectDir, 'src/foundation'), + layout: join(projectDir, 'src/layout'), + tokens: join(projectDir, 'src/tokens'), + }); + }); + + it('adds native Emulsify Twig functions to generic Twig rendering options', () => { + projectDir = makeTempProject(); + mkdirSync(join(projectDir, 'src/components'), { recursive: true }); + + expect( + Object.keys(makeTwigPluginOptions(makeEnv(projectDir)).functions), + ).toEqual(['add_attributes', 'bem']); + }); + + it('can transform the same Twig module more than once', () => { + projectDir = makeTempProject(); + const cardFile = join(projectDir, 'src/components/card/card.twig'); + mkdirSync(join(projectDir, 'src/components/card'), { recursive: true }); + writeFileSync(cardFile, '
{{ title }}
'); + + const twigPlugin = makeTwigModulePlugin(makeEnv(projectDir)); + const first = transformTwigModule(twigPlugin, cardFile); + const second = transformTwigModule(twigPlugin, cardFile); + + expect(first.code).not.toContain('An error occurred whilst compiling'); + expect(second.code).not.toContain('An error occurred whilst compiling'); + expect(second.code).not.toContain( + 'There is already a template with the ID', + ); + expect(renderGeneratedTwigModule(second.code, { title: 'Card' })).toContain( + '
Card
', + ); + }); + + it('can transform a child Twig module before a parent includes it', () => { + projectDir = makeTempProject(); + const headingFile = join(projectDir, 'src/components/heading/heading.twig'); + const accordionFile = join( + projectDir, + 'src/components/accordion/accordion.twig', + ); + mkdirSync(join(projectDir, 'src/components/heading'), { + recursive: true, + }); + mkdirSync(join(projectDir, 'src/components/accordion'), { + recursive: true, + }); + writeFileSync(headingFile, '

{{ title }}

'); + writeFileSync(accordionFile, twigInclude(headingFile)); + + const twigPlugin = makeTwigModulePlugin(makeEnv(projectDir)); + const child = transformTwigModule(twigPlugin, headingFile); + const parent = transformTwigModule(twigPlugin, accordionFile); + + expect(child.code).not.toContain('An error occurred whilst compiling'); + expect(parent.code).not.toContain('An error occurred whilst compiling'); + expect(parent.code).not.toContain( + 'There is already a template with the ID', + ); + expect( + renderGeneratedTwigModule(parent.code, { title: 'Included' }), + ).toContain('

Included

'); + }); + + it('renders nested include and embed dependencies through namespaces', () => { + projectDir = makeTempProject(); + const accordionDir = join(projectDir, 'src/components/accordion'); + const headingDir = join(projectDir, 'src/components/heading'); + const layoutDir = join(projectDir, 'src/layout/container'); + const accordionFile = join(accordionDir, 'accordion.twig'); + mkdirSync(accordionDir, { recursive: true }); + mkdirSync(headingDir, { recursive: true }); + mkdirSync(layoutDir, { recursive: true }); + writeFileSync(join(headingDir, 'heading.twig'), '

{{ title }}

'); + writeFileSync( + join(layoutDir, 'container.twig'), + '
{% block content %}{% endblock %}
', + ); + writeFileSync(join(accordionDir, '_body.twig'), '

{{ body }}

'); + writeFileSync( + accordionFile, + [ + twigInclude('@components/heading/heading.twig'), + twigEmbed('@layout/container/container.twig'), + ' {% block content %}', + ` ${twigInclude('./_body.twig')}`, + ' {% endblock %}', + '{% endembed %}', + ].join('\n'), + ); + + const twigPlugin = makeTwigModulePlugin(makeEnv(projectDir)); + const transformed = transformTwigModule(twigPlugin, accordionFile); + const output = renderGeneratedTwigModule(transformed.code, { + title: 'Accordion', + body: 'Panel body', + }); + + expect(transformed.code).not.toContain( + 'An error occurred whilst compiling', + ); + expect(output).toContain('

Accordion

'); + expect(output).toContain('
'); + expect(output).toContain('

Panel body

'); + }); +}); diff --git a/config/vite/plugins/__tests__/vituum-patch.test.js b/config/vite/plugins/__tests__/vituum-patch.test.js new file mode 100644 index 0000000..fde27d6 --- /dev/null +++ b/config/vite/plugins/__tests__/vituum-patch.test.js @@ -0,0 +1,84 @@ +/** + * @file Tests for guarded Vituum Twig plugin patching. + */ + +import { makeTwigPlugins } from '../vituum-patch.js'; + +let mockTwigPluginResult; + +jest.mock('@vituum/vite-plugin-twig', () => ({ + __esModule: true, + default: jest.fn(() => mockTwigPluginResult), +})); + +const twigPlugin = (overrides = {}) => ({ + name: '@vituum/vite-plugin-twig', + buildStart: jest.fn(), + buildEnd: jest.fn(), + ...overrides, +}); + +const bundlePlugin = (overrides = {}) => ({ + name: '@vituum/vite-plugin-core:bundle', + ...overrides, +}); + +const makePatchedPlugins = () => makeTwigPlugins({}, {}); + +describe('makeTwigPlugins', () => { + beforeEach(() => { + mockTwigPluginResult = [twigPlugin(), bundlePlugin()]; + }); + + it('removes Vituum bundle plugin and strips incompatible Twig build hooks', () => { + const plugins = makePatchedPlugins(); + const names = plugins.map((pluginOption) => pluginOption?.name); + const patchedTwigPlugin = plugins.find( + (pluginOption) => pluginOption?.name === '@vituum/vite-plugin-twig', + ); + + expect(names).toContain('@vituum/vite-plugin-twig'); + expect(names).not.toContain('@vituum/vite-plugin-core:bundle'); + expect(patchedTwigPlugin).not.toHaveProperty('buildStart'); + expect(patchedTwigPlugin).not.toHaveProperty('buildEnd'); + }); + + it('throws when the expected Vituum Twig plugin is missing', () => { + mockTwigPluginResult = [ + bundlePlugin(), + { name: '@vituum/vite-plugin-other' }, + ]; + + expect(() => makePatchedPlugins()).toThrow( + /expected '@vituum\/vite-plugin-twig' not found/, + ); + }); + + it('throws when the Vituum Twig plugin has none of the targeted hooks', () => { + mockTwigPluginResult = [ + { + name: '@vituum/vite-plugin-twig', + transform: jest.fn(), + }, + bundlePlugin(), + ]; + + expect(() => makePatchedPlugins()).toThrow( + /did not expose any targeted hooks to strip/, + ); + }); + + it('preserves extra hooks on the Vituum Twig plugin', () => { + const transform = jest.fn(); + mockTwigPluginResult = [twigPlugin({ transform }), bundlePlugin()]; + + const plugins = makePatchedPlugins(); + const patchedTwigPlugin = plugins.find( + (pluginOption) => pluginOption?.name === '@vituum/vite-plugin-twig', + ); + + expect(patchedTwigPlugin).toHaveProperty('transform', transform); + expect(patchedTwigPlugin).not.toHaveProperty('buildStart'); + expect(patchedTwigPlugin).not.toHaveProperty('buildEnd'); + }); +}); diff --git a/config/vite/plugins/__tests__/yaml-module.test.js b/config/vite/plugins/__tests__/yaml-module.test.js new file mode 100644 index 0000000..64a87b4 --- /dev/null +++ b/config/vite/plugins/__tests__/yaml-module.test.js @@ -0,0 +1,65 @@ +/** + * @file Tests for YAML module plugin exports and request handling. + */ + +import { join } from 'path'; + +import { yamlModulePlugin } from '../yaml-module.js'; + +const projectDir = '/tmp/emulsify-core-yaml-plugin-test'; + +describe('YAML module plugin', () => { + it('transforms YAML imports into JavaScript modules with default and named exports', () => { + const yamlPlugin = yamlModulePlugin(); + const result = yamlPlugin.transform( + [ + 'name: Accordion', + 'props:', + ' type: object', + 'slots:', + ' content:', + ' title: Content', + '$schema: https://example.com/schema.json', + 'invalid-key: omitted', + 'default: reserved', + ].join('\n'), + `${join(projectDir, 'src/components/accordion/accordion.component.yml')}?import`, + ); + + expect(result).toEqual({ + code: [ + 'export const name = "Accordion";', + 'export const props = {"type":"object"};', + 'export const slots = {"content":{"title":"Content"}};', + 'export default {"name":"Accordion","props":{"type":"object"},"slots":{"content":{"title":"Content"}},"$schema":"https://example.com/schema.json","invalid-key":"omitted","default":"reserved"};', + '', + ].join('\n'), + map: null, + }); + expect(result.code).not.toContain('export const $schema'); + expect(result.code).not.toContain('export const invalid-key'); + expect(result.code).not.toContain('export const default'); + }); + + it('preserves default-only YAML modules for non-object values', () => { + const yamlPlugin = yamlModulePlugin(); + + expect( + yamlPlugin.transform( + ['- one', '- two'].join('\n'), + join(projectDir, 'src/components/list/list.component.yml'), + ), + ).toEqual({ + code: 'export default ["one","two"];\n', + map: null, + }); + }); + + it('ignores raw and URL YAML requests', () => { + const yamlPlugin = yamlModulePlugin(); + const id = join(projectDir, 'src/components/card/card.component.yml'); + + expect(yamlPlugin.transform('name: Raw', `${id}?raw`)).toBeNull(); + expect(yamlPlugin.transform('name: Url', `${id}?url`)).toBeNull(); + }); +}); diff --git a/config/vite/plugins/copy-src-assets.js b/config/vite/plugins/copy-src-assets.js new file mode 100644 index 0000000..98662b3 --- /dev/null +++ b/config/vite/plugins/copy-src-assets.js @@ -0,0 +1,76 @@ +/** + * @file Static source asset copy plugin. + * + * Copies non-code source assets beside the JS/CSS/Twig output that references + * them, preserving component and global routing semantics. + */ + +import { copyFileSync, mkdirSync } from 'fs'; +import { dirname, join } from 'path'; + +import { + copiedComponentOutputPath, + copiedGlobalOutputPath, + findSourceRoot, +} from '../project-structure.js'; +import { + createSourceFileIndex, + isStaticSourceAsset, +} from './source-file-index.js'; + +/** + * Copy non-code assets from source roots to `dist/`. + * + * @param {{ structure: object, sourceFileIndex?: object }} opts - Plugin options. + * @returns {import('vite').PluginOption} Copy plugin. + */ +export function copyAllSrcAssetsPlugin({ + structure, + sourceFileIndex = createSourceFileIndex(structure), +}) { + let outDir = 'dist'; + + const copyToOutDir = (absPath, relDest) => { + if (!relDest) return; + const destPath = join(outDir, relDest); + mkdirSync(dirname(destPath), { recursive: true }); + try { + copyFileSync(absPath, destPath); + } catch { + /* noop */ + } + }; + + return { + name: 'emulsify-copy-all-src-assets', + apply: 'build', + enforce: 'post', + + /** Capture outDir. */ + configResolved(cfg) { + outDir = cfg.build?.outDir || 'dist'; + }, + + /** Copy before the mirror plugin moves dist/components to the project root. */ + writeBundle() { + for (const file of sourceFileIndex.componentFiles()) { + if (!isStaticSourceAsset(file.absPath)) continue; + copyToOutDir( + file.absPath, + copiedComponentOutputPath(file.absPath, structure), + ); + } + + for (const file of sourceFileIndex.globalFiles()) { + if (!isStaticSourceAsset(file.absPath)) continue; + if (findSourceRoot(file.absPath, structure.componentRootRecords)) { + continue; + } + copyToOutDir( + file.absPath, + copiedGlobalOutputPath(file.absPath, structure), + ); + } + }, + }; +} diff --git a/config/vite/plugins/copy-twig-files.js b/config/vite/plugins/copy-twig-files.js new file mode 100644 index 0000000..8c74b0b --- /dev/null +++ b/config/vite/plugins/copy-twig-files.js @@ -0,0 +1,84 @@ +/** + * @file Twig template and component metadata copy plugin. + * + * Copies canonical source Twig files and component metadata to the emitted dist + * structure using the same routing rules as compiled JS and CSS entries. + */ + +import { copyFileSync, mkdirSync } from 'fs'; +import { dirname, join } from 'path'; + +import { + copiedComponentOutputPath, + copiedGlobalOutputPath, +} from '../project-structure.js'; +import { + createSourceFileIndex, + isComponentMetadataFile, +} from './source-file-index.js'; + +/** Determine whether a Twig file is a partial (filename starts with `_`). */ +const isPartial = (filePath) => + (filePath.split('/')?.pop() || '').trim().startsWith('_'); + +/** + * Copy Twig templates and component metadata to `dist/`. + * + * @param {{ structure: object, sourceFileIndex?: object }} opts - Plugin options. + * @returns {import('vite').PluginOption} Copy plugin. + */ +export function copyTwigFilesPlugin({ + structure, + sourceFileIndex = createSourceFileIndex(structure), +}) { + let outDir = 'dist'; + + const copyToOutDir = (absPath, relDest) => { + if (!relDest) return; + const destPath = join(outDir, relDest); + mkdirSync(dirname(destPath), { recursive: true }); + try { + copyFileSync(absPath, destPath); + } catch { + /* noop */ + } + }; + + return { + name: 'emulsify-copy-twig-files', + apply: 'build', + enforce: 'post', + + /** Capture the final outDir. */ + configResolved(cfg) { + outDir = cfg.build?.outDir || 'dist'; + }, + + /** Copy before the mirror plugin moves dist/components to the project root. */ + writeBundle() { + for (const file of sourceFileIndex.componentFiles()) { + if (file.absPath.endsWith('.twig')) { + if (isPartial(file.relPath)) continue; + copyToOutDir( + file.absPath, + copiedComponentOutputPath(file.absPath, structure), + ); + } else if (isComponentMetadataFile(file.absPath)) { + copyToOutDir( + file.absPath, + copiedComponentOutputPath(file.absPath, structure), + ); + } + } + + for (const file of sourceFileIndex.globalFiles()) { + if (!file.absPath.endsWith('.twig')) continue; + if (isPartial(file.relPath)) continue; + copyToOutDir( + file.absPath, + copiedGlobalOutputPath(file.absPath, structure), + ); + } + }, + }; +} diff --git a/config/vite/plugins/css-asset-relativizer.js b/config/vite/plugins/css-asset-relativizer.js new file mode 100644 index 0000000..69b6503 --- /dev/null +++ b/config/vite/plugins/css-asset-relativizer.js @@ -0,0 +1,40 @@ +/** + * @file CSS asset URL relativizer plugin. + * + * Rewrites emitted CSS references to root assets so nested CSS files can keep + * resolving copied assets correctly from their final output directories. + */ + +import { posix as pathPosix } from 'path'; + +/** + * Rewrites any `url(assets/...)` found in emitted CSS to a path relative to the + * CSS file's directory. + * + * @param {{ assetsRoot?: string }} [opts] - Plugin options. + * @returns {import('vite').PluginOption} CSS asset URL plugin. + */ +export function cssAssetUrlRelativizer({ assetsRoot = 'assets' } = {}) { + return { + name: 'emulsify-css-asset-url-relativizer', + apply: 'build', + generateBundle(_, bundle) { + for (const [fileName, chunk] of Object.entries(bundle)) { + if (chunk.type !== 'asset') continue; + if (!fileName.endsWith('.css')) continue; + if (typeof chunk.source !== 'string') continue; + + const fromDir = pathPosix.dirname(fileName); + + chunk.source = chunk.source.replace( + /url\((['"]?)\/?assets\/([^)'"]+)\1\)/g, + (match, quote = '', rest) => { + const target = pathPosix.join(assetsRoot, rest); + const rel = pathPosix.relative(fromDir, target); + return `url(${quote}${rel}${quote})`; + }, + ); + } + }, + }; +} diff --git a/config/vite/plugins/index.js b/config/vite/plugins/index.js new file mode 100644 index 0000000..2724a47 --- /dev/null +++ b/config/vite/plugins/index.js @@ -0,0 +1,96 @@ +/** + * @file Vite plugin composition for Emulsify. + * + * Assembles the shared plugin chain used by Vite and Storybook while delegating + * each individual plugin concern to focused internal modules. + */ + +import sassGlobImports from 'vite-plugin-sass-glob-import'; + +import { getPlatformAdapter } from '../platforms.js'; +import { resolveProjectStructure } from '../project-structure.js'; +import { toPosixPath } from '../utils/paths.js'; +import { copyAllSrcAssetsPlugin } from './copy-src-assets.js'; +import { copyTwigFilesPlugin } from './copy-twig-files.js'; +import { cssAssetUrlRelativizer } from './css-asset-relativizer.js'; +import { mirrorComponentsToRoot } from './mirror-components.js'; +import { createSourceFileIndex } from './source-file-index.js'; +import { svgSpriteFilePlugin } from './svg-sprite.js'; +import { + emulsifyTwigModulePlugin, + makeTwigPluginOptions, +} from './twig-module.js'; +import { virtualTwigGlobsPlugin } from './virtual-twig-globs.js'; +import { makeTwigPlugins } from './vituum-patch.js'; +import { yamlModulePlugin } from './yaml-module.js'; + +/** + * Create the Vite plugin array used by Emulsify builds. + * + * @param {{ + * projectDir: string, + * platform: string, + * srcDir: string, + * srcExists: boolean, + * structureOverrides?: boolean + * }} env - Project environment. + * @returns {import('vite').PluginOption[]} Emulsify Vite plugins. + */ +export function makePlugins(env) { + const { projectDir, platform } = env; + const platformAdapter = env.platformAdapter || getPlatformAdapter(platform); + const structure = + env.projectStructure || + resolveProjectStructure({ + ...env, + platformAdapter, + }); + const envWithStructure = { ...env, projectStructure: structure }; + const twigOptions = makeTwigPluginOptions(env); + const sourceFileIndex = createSourceFileIndex(structure); + + const basePlugins = [ + virtualTwigGlobsPlugin(envWithStructure), + + emulsifyTwigModulePlugin(twigOptions), + + // Generic Twig rendering for dev/preview. + ...makeTwigPlugins(env, twigOptions), + + // Emit a physical dist/assets/icons.svg sprite. + svgSpriteFilePlugin({ + include: [ + `${toPosixPath(projectDir)}/assets/icons/**/*.svg`, + 'assets/icons/**/*.svg', + 'src/assets/icons/**/*.svg', + 'src/**/icons/**/*.svg', + ], + symbolId: '[name]', + }), + + // Sass glob imports preserve existing component stylesheet patterns. + sassGlobImports(), + + // YAML support lets component metadata import into Vite modules. + yamlModulePlugin(), + + // Keep CSS asset URLs relative to the emitted CSS location. + cssAssetUrlRelativizer({ assetsRoot: 'assets' }), + ]; + + return [ + ...basePlugins, + + // Copy Twig templates and component metadata beside compiled assets. + copyTwigFilesPlugin({ structure, sourceFileIndex }), + + // Copy every non-code asset under src with the same routing. + copyAllSrcAssetsPlugin({ structure, sourceFileIndex }), + + // Drupal projects with src mirror dist/components back to ./components. + mirrorComponentsToRoot({ + enabled: structure.mirrorComponentOutput, + projectDir, + }), + ]; +} diff --git a/config/vite/plugins/mirror-components.js b/config/vite/plugins/mirror-components.js new file mode 100644 index 0000000..9dcf588 --- /dev/null +++ b/config/vite/plugins/mirror-components.js @@ -0,0 +1,302 @@ +/** + * @file Drupal component mirror plugin. + * + * Mirrors built `dist/components/**` files back to project-root `components/**` + * for Drupal SDC projects that author canonical components under `src/`. + */ + +import { + copyFileSync, + lstatSync, + mkdirSync, + readFileSync, + readdirSync, + renameSync, + rmdirSync, + statSync, + unlinkSync, + writeFileSync, +} from 'fs'; +import { basename, dirname, join, resolve } from 'path'; + +import { safeExists, safeReadJson } from '../utils/fs-safe.js'; +import { walkFiles } from './source-file-index.js'; + +const MIRROR_STATE_FILE = '.emulsify-mirror-state.json'; + +/** + * Resolve the installed Core package version without relying on import.meta so + * Jest's CommonJS transform can load this Vite plugin module. + * + * @param {string} projectDir - Project directory running the build. + * @returns {string} Emulsify Core package version. + */ +const resolvePackageVersion = (projectDir) => { + const candidates = [ + join(projectDir, 'node_modules/@emulsify/core/package.json'), + join(process.cwd(), 'node_modules/@emulsify/core/package.json'), + join(process.cwd(), 'package.json'), + ]; + + for (const candidate of candidates) { + const candidatePackage = safeReadJson(candidate).data; + if ( + candidatePackage?.name === '@emulsify/core' && + candidatePackage.version + ) { + return candidatePackage.version; + } + } + + return '0.0.0'; +}; + +/** + * Remove empty parent directories from a start directory up to, but not including, + * a stopping boundary directory. + * + * @param {string} startDir - Directory to prune from. + * @param {string} stopAtDir - Boundary directory. + */ +const pruneEmptyDirsUpTo = (startDir, stopAtDir) => { + const stopAbs = resolve(stopAtDir); + let cursor = resolve(startDir); + + const isEmpty = (dir) => { + try { + // eslint-disable-next-line security/detect-non-literal-fs-filename + return readdirSync(dir).length === 0; + } catch { + return false; + } + }; + + while (cursor.startsWith(stopAbs)) { + if (!isEmpty(cursor)) break; + + try { + // eslint-disable-next-line security/detect-non-literal-fs-filename + rmdirSync(cursor); + } catch { + // Stop at the first directory that cannot be removed. + break; + } + + const parent = dirname(cursor); + if (parent === cursor || parent === stopAbs) break; + cursor = parent; + } +}; + +/** + * Determine whether two files already contain the same bytes. + * + * @param {string} sourceFile - Source file path. + * @param {string} destinationFile - Destination file path. + * @returns {boolean} TRUE when both files have identical bytes. + */ +const filesHaveSameBytes = (sourceFile, destinationFile) => { + try { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const sourceStats = statSync(sourceFile); + // eslint-disable-next-line security/detect-non-literal-fs-filename + const destinationStats = statSync(destinationFile); + if (!destinationStats.isFile()) return false; + if (sourceStats.size !== destinationStats.size) return false; + if (sourceStats.size === 0) return true; + + return readFileSync(sourceFile).equals(readFileSync(destinationFile)); + } catch { + return false; + } +}; + +/** + * Determine whether a filesystem path is a symbolic link. + * + * @param {string} filePath - File path to inspect. + * @returns {boolean} TRUE when the path exists and is a symlink. + */ +const isSymlink = (filePath) => { + try { + // eslint-disable-next-line security/detect-non-literal-fs-filename + return lstatSync(filePath).isSymbolicLink(); + } catch { + return false; + } +}; + +/** + * Remove a source file, ignoring races where it was already removed. + * + * @param {string} sourceFile - Source file path. + */ +const removeSourceFile = (sourceFile) => { + try { + // eslint-disable-next-line security/detect-non-literal-fs-filename + unlinkSync(sourceFile); + } catch (error) { + if (error?.code !== 'ENOENT') throw error; + } +}; + +/** + * Create a temporary path beside the final destination so rename is atomic. + * + * @param {string} destinationFile - Destination file path. + * @returns {string} Adjacent temporary path. + */ +const createTempDestination = (destinationFile) => + join( + dirname(destinationFile), + `.${basename(destinationFile)}.${process.pid}.${Date.now()}.${Math.random() + .toString(36) + .slice(2)}.tmp`, + ); + +/** + * Copy across filesystems or symlink boundaries, then rename into place. + * + * @param {string} sourceFile - Source file path. + * @param {string} destinationFile - Destination file path. + */ +const copyFileIntoPlace = (sourceFile, destinationFile) => { + const tempDestination = createTempDestination(destinationFile); + + try { + copyFileSync(sourceFile, tempDestination); + // eslint-disable-next-line security/detect-non-literal-fs-filename + renameSync(tempDestination, destinationFile); + removeSourceFile(sourceFile); + } catch (error) { + try { + // eslint-disable-next-line security/detect-non-literal-fs-filename + unlinkSync(tempDestination); + } catch { + /* noop */ + } + throw error; + } +}; + +/** + * Move a mirrored file into place without exposing copy-then-unlink state. + * + * @param {string} sourceFile - Built file under dist. + * @param {string} destinationFile - Mirrored project-root destination. + */ +const moveFileIntoPlace = (sourceFile, destinationFile) => { + mkdirSync(dirname(destinationFile), { recursive: true }); + + if (filesHaveSameBytes(sourceFile, destinationFile)) { + removeSourceFile(sourceFile); + return; + } + + if (isSymlink(sourceFile) || isSymlink(destinationFile)) { + copyFileIntoPlace(sourceFile, destinationFile); + return; + } + + try { + // eslint-disable-next-line security/detect-non-literal-fs-filename + renameSync(sourceFile, destinationFile); + } catch (error) { + if (error?.code !== 'EXDEV') throw error; + copyFileIntoPlace(sourceFile, destinationFile); + } +}; + +/** + * Safely read the previous mirror state marker. + * + * @param {string} markerFile - Marker file path. + * @returns {object|undefined} Parsed marker state. + */ +const readMirrorState = (markerFile) => { + const result = safeReadJson(markerFile); + return result.data; +}; + +/** + * Write a mirror state marker. + * + * @param {string} markerFile - Marker file path. + * @param {{ startedAt: string, completedAt: string|null, version: string }} state - Marker state. + */ +const writeMirrorState = (markerFile, state) => { + mkdirSync(dirname(markerFile), { recursive: true }); + // eslint-disable-next-line security/detect-non-literal-fs-filename + writeFileSync(markerFile, `${JSON.stringify(state, null, 2)}\n`); +}; + +/** + * Warn if the previous mirror pass did not complete. + * + * @param {string} markerFile - Marker file path. + */ +const warnOnInterruptedMirror = (markerFile) => { + const previousState = readMirrorState(markerFile); + if (previousState?.completedAt !== null) return; + + console.warn( + `Previous Emulsify component mirror build was interrupted before completion; stale mirrored files may exist. Marker: ${markerFile}`, + ); +}; + +/** + * Mirror built component files to the project root `./components/` directory. + * + * @param {{ enabled: boolean, projectDir: string }} opts - Plugin options. + * @returns {import('vite').PluginOption} Drupal mirror plugin. + */ +export function mirrorComponentsToRoot({ enabled, projectDir }) { + let outDir = 'dist'; + return { + name: 'emulsify-mirror-components-to-root', + apply: 'build', + enforce: 'post', + configResolved(cfg) { + outDir = cfg.build?.outDir || 'dist'; + }, + writeBundle() { + if (!enabled) return; + const markerFile = join(outDir, MIRROR_STATE_FILE); + warnOnInterruptedMirror(markerFile); + + const startedAt = new Date().toISOString(); + const mirrorState = { + startedAt, + completedAt: null, + version: resolvePackageVersion(projectDir), + }; + writeMirrorState(markerFile, mirrorState); + + // Vite has written files by writeBundle, while closeBundle can overlap + // with the next watch cycle observing a partially mirrored dist tree. + const distComponents = join(outDir, 'components'); + if (safeExists(distComponents)) { + for (const srcFile of walkFiles(distComponents)) { + const relFromOutDir = srcFile.slice(join(outDir, '').length); + const destFile = join(projectDir, relFromOutDir); + + try { + moveFileIntoPlace(srcFile, destFile); + pruneEmptyDirsUpTo(dirname(srcFile), distComponents); + } catch (e) { + console.warn( + `Mirror copy failed for ${relFromOutDir}: ${e?.message || e}`, + ); + } + } + + pruneEmptyDirsUpTo(distComponents, outDir); + } + + writeMirrorState(markerFile, { + ...mirrorState, + completedAt: new Date().toISOString(), + }); + }, + }; +} diff --git a/config/vite/plugins/source-file-index.js b/config/vite/plugins/source-file-index.js new file mode 100644 index 0000000..bb427b9 --- /dev/null +++ b/config/vite/plugins/source-file-index.js @@ -0,0 +1,157 @@ +/** + * @file Source file discovery helpers shared by Emulsify Vite copy plugins. + * + * This module walks resolved source roots once, then exposes filtered views for + * component and global files so copy plugins share the same filesystem model. + */ + +import { readdirSync, statSync } from 'fs'; +import { join, relative, sep } from 'path'; + +import { relativeFrom } from '../project-structure.js'; + +/** + * Depth-first walk to list every file under a given root. + * + * @param {string} rootDir - Directory to traverse. + * @param {{ shouldSkipDir?: (dir: string) => boolean }} [options] - Traversal options. + * @returns {string[]} Absolute file paths. + */ +export function walkFiles(rootDir, { shouldSkipDir = () => false } = {}) { + const files = []; + const stack = [rootDir]; + + while (stack.length) { + const currentDir = stack.pop(); + if (!currentDir) continue; + + let entryNames = []; + try { + // eslint-disable-next-line security/detect-non-literal-fs-filename + entryNames = readdirSync(currentDir).sort(); + } catch { + // Skip unreadable directories and keep walking the remaining stack. + continue; + } + + for (const name of entryNames) { + const fullPath = join(currentDir, name); + try { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const stats = statSync(fullPath); + if (stats.isDirectory()) { + if (!shouldSkipDir(fullPath)) stack.push(fullPath); + } else files.push(fullPath); + } catch { + // Ignore unreadable entries so one file does not stop the copy pass. + } + } + } + + return files; +} + +/** + * Determine whether a directory is the same as, or nested inside, another one. + * + * @param {string} candidateDir - Directory to test. + * @param {string} rootDir - Boundary directory. + * @returns {boolean} TRUE when candidateDir is the root or inside it. + */ +export function isSameOrInsideDir(candidateDir, rootDir) { + const rel = relative(rootDir, candidateDir); + return !rel || (!rel.startsWith('..') && !rel.includes(`..${sep}`)); +} + +/** + * Determine whether a file is component metadata copied beside Twig templates. + * + * @param {string} filePath - Absolute or relative file path. + * @returns {boolean} TRUE for component metadata files. + */ +export const isComponentMetadataFile = (filePath) => + /\.component\.(yml|yaml|json)$/i.test(filePath); + +/** + * Determine whether a file should be copied by the static asset pass. + * + * @param {string} filePath - Absolute or relative file path. + * @returns {boolean} TRUE for non-code source assets. + */ +export const isStaticSourceAsset = (filePath) => + !/\.(js|scss|twig|map)$/i.test(filePath) && + !isComponentMetadataFile(filePath); + +/** + * Build the roots that should not be crawled during a global source pass. + * + * @param {{ directory: string }} globalRoot - Global source root record. + * @param {{ directory: string }[]} componentRoots - Component source root records. + * @returns {string[]} Directory paths to skip. + */ +const globalTraversalSkipRoots = (globalRoot, componentRoots) => { + const configuredSkips = [ + join(globalRoot.directory, 'components'), + join(globalRoot.directory, 'util'), + ]; + const nestedComponentRoots = componentRoots + .map((root) => root.directory) + .filter( + (directory) => + directory !== globalRoot.directory && + isSameOrInsideDir(directory, globalRoot.directory), + ); + + return [...configuredSkips, ...nestedComponentRoots]; +}; + +/** + * Create a lazy, shared index of files under the resolved project source roots. + * + * @param {object} structure - Resolved project structure. + * @returns {{ + * all: () => Array, + * componentFiles: () => Array, + * globalFiles: () => Array + * }} Indexed file accessors. + */ +export function createSourceFileIndex(structure) { + let indexedFiles = null; + + const indexRoot = (root, rootType, options = {}) => + walkFiles(root.directory, options).map((absPath) => ({ + absPath, + relPath: relativeFrom(absPath, root.directory), + root, + rootType, + })); + + const build = () => { + if (indexedFiles) return indexedFiles; + + const componentFiles = structure.componentRootRecords.flatMap((root) => + indexRoot(root, 'component'), + ); + const globalFiles = structure.globalRootRecords.flatMap((root) => { + const skipRoots = globalTraversalSkipRoots( + root, + structure.componentRootRecords, + ); + + return indexRoot(root, 'global', { + shouldSkipDir: (directory) => + skipRoots.some((skipRoot) => isSameOrInsideDir(directory, skipRoot)), + }); + }); + + indexedFiles = [...componentFiles, ...globalFiles]; + return indexedFiles; + }; + + return { + all: build, + componentFiles: () => + build().filter((entry) => entry.rootType === 'component'), + globalFiles: () => build().filter((entry) => entry.rootType === 'global'), + }; +} diff --git a/config/vite/plugins/svg-sprite.js b/config/vite/plugins/svg-sprite.js new file mode 100644 index 0000000..f07aa17 --- /dev/null +++ b/config/vite/plugins/svg-sprite.js @@ -0,0 +1,117 @@ +/** + * @file SVG sprite file plugin. + * + * Builds a physical `dist/assets/icons.svg` sprite from configured SVG globs so + * Drupal and static consumers can reference a stable emitted spritemap asset. + */ + +import { readFileSync } from 'fs'; +import { basename } from 'path'; +import { globSync } from 'glob'; + +import { toPosixPath } from '../utils/paths.js'; +import { unique } from '../utils/unique.js'; + +/** + * Builds a single SVG sprite file from a set of icon globs. + * + * @param {{ include: string|string[], symbolId?: string }} options - Plugin options. + * @returns {import('vite').PluginOption} SVG sprite plugin. + */ +export function svgSpriteFilePlugin({ include, symbolId = '[name]' }) { + const toArray = (x) => (Array.isArray(x) ? x : [x]).filter(Boolean); + + /** @type {string[]} */ + let patterns = []; + /** @type {string[]} */ + let iconFiles = []; + let iconFilesResolved = false; + + const collectIconFiles = () => { + if (iconFilesResolved) return iconFiles; + iconFiles = unique( + patterns.flatMap((p) => globSync(p)).filter(Boolean), + ).sort((a, b) => toPosixPath(a).localeCompare(toPosixPath(b))); + iconFilesResolved = true; + return iconFiles; + }; + + return { + name: 'emulsify-svg-sprite-file', + apply: 'build', + + /** Register icons for watch. */ + buildStart() { + patterns = toArray(include).map(toPosixPath); + iconFilesResolved = false; + for (const f of collectIconFiles()) { + try { + this.addWatchFile(f); + } catch { + /* noop */ + } + } + }, + + /** Concatenate all matched SVGs into a single sprite. */ + generateBundle() { + const files = collectIconFiles(); + + if (!files.length) return; + + const used = new Set(); + const makeId = (abs) => { + const stem = basename(abs).replace(/\.svg$/i, ''); + let id = symbolId + .replace('[name]', stem) + .toLowerCase() + .replace(/[^a-z0-9_-]+/g, '-') + .replace(/^-+|-+$/g, ''); + if (!used.has(id)) { + used.add(id); + return id; + } + let i = 2; + while (used.has(`${id}-${i}`)) i += 1; + id = `${id}-${i}`; + used.add(id); + return id; + }; + + const symbols = files + .map((abs) => { + let content = ''; + try { + // eslint-disable-next-line security/detect-non-literal-fs-filename + content = readFileSync(abs, 'utf8'); + } catch { + return ''; + } + const m = content.match(/]*)>([\s\S]*?)<\/svg>/i); + const inner = (m ? m[2] : content) + .replace(/<\/*symbol[^>]*>/gi, '') + .replace(/<\/*defs[^>]*>/gi, '') + // Drop namespace-prefixed attributes that lose their prefix in the merged sprite. + .replace(/\s+[a-zA-Z0-9_-]+:[a-zA-Z0-9_.-]+="[^"]*"/g, '') + .trim(); + const attrs = m ? m[1] : ''; + const vb = attrs.match(/\bviewBox="([^"]+)"/i); + const viewBoxAttr = vb ? ` viewBox="${vb[1]}"` : ''; + return `${inner}`; + }) + .filter(Boolean); + + const sprite = [ + '', + ...symbols, + '\n', + ].join('\n'); + + this.emitFile({ + type: 'asset', + fileName: 'assets/icons.svg', + source: sprite, + }); + }, + }; +} diff --git a/config/vite/plugins/twig-module.js b/config/vite/plugins/twig-module.js new file mode 100644 index 0000000..24f0a32 --- /dev/null +++ b/config/vite/plugins/twig-module.js @@ -0,0 +1,469 @@ +/** + * @file Twig module plugin and Twig namespace option helpers. + * + * The plugin turns Twig file imports into render functions for Storybook and + * Vite consumers while recursively compiling referenced Twig dependencies. + */ + +import { readFileSync, statSync } from 'fs'; +import { basename, dirname, resolve } from 'path'; +import Twig from 'twig'; + +import { + getTwigFunctionMap, + registerTwigExtensions, +} from '../../../src/extensions/twig/index.js'; +import { resolveProjectStructure } from '../project-structure.js'; +import { firstExistingPath } from '../utils/fs-safe.js'; +import { toPosixPath } from '../utils/paths.js'; +import { unique } from '../utils/unique.js'; + +/** Twig token types that can reference another template file. */ +const includeTokenTypes = [ + 'Twig.logic.type.embed', + 'Twig.logic.type.extends', + 'Twig.logic.type.from', + 'Twig.logic.type.import', + 'Twig.logic.type.include', +]; + +/** + * Determine whether a Vite request should compile as a Twig render module. + * + * @param {string} id - Vite module id, including an optional query string. + * @returns {boolean} TRUE when the request is a renderable Twig module. + */ +const isTwigModuleRequest = (id) => { + const [filePath, query = ''] = id.split('?'); + if (!filePath.endsWith('.twig')) return false; + return !query || query === 'twig' || !/(^|&)(raw|url)\b/.test(query); +}; + +/** + * Remove the Vite query string from a module id. + * + * @param {string} id - Vite module id. + * @returns {string} Filesystem path without query parameters. + */ +const stripRequestQuery = (id) => id.split('?')[0]; + +/** + * Extract referenced Twig templates from compiled Twig token trees. + * + * @param {Array} [tokens=[]] - Twig token tree. + * @returns {string[]} Referenced template paths. + */ +const pluckIncludes = (tokens = []) => [ + ...tokens + .filter((token) => includeTokenTypes.includes(token.token?.type)) + .flatMap((token) => + (token.token?.stack || []) + .map((stack) => stack.value) + .filter((value) => typeof value === 'string'), + ), + ...tokens.flatMap((token) => pluckIncludes(token.token?.output || [])), +]; + +/** + * Build likely filesystem candidates for a Twig template reference. + * + * @param {string} baseDir - Directory used as the resolution root. + * @param {string} templatePath - Template path from Twig source. + * @returns {string[]} Candidate absolute paths. + */ +const fileCandidates = (baseDir, templatePath) => { + const normalizedTemplatePath = toPosixPath(templatePath); + const withoutTwigExt = normalizedTemplatePath.replace(/\.twig$/i, ''); + const stem = basename(withoutTwigExt); + + return unique( + [ + resolve(baseDir, normalizedTemplatePath), + resolve(baseDir, `${normalizedTemplatePath}.twig`), + resolve(baseDir, `${normalizedTemplatePath}.html.twig`), + resolve(baseDir, withoutTwigExt, `${stem}.twig`), + resolve(baseDir, withoutTwigExt, `${stem}.html.twig`), + ].filter(Boolean), + ); +}; + +/** + * Return the first candidate that exists as a file. + * + * @param {string[]} paths - Candidate absolute paths. + * @returns {string|undefined} Existing file path. + */ +const resolveExistingFile = (paths) => + paths.filter(Boolean).find((filePath) => { + try { + // eslint-disable-next-line security/detect-non-literal-fs-filename + return statSync(filePath).isFile(); + } catch { + return false; + } + }); + +/** + * Resolve Twig namespace syntax to a namespace root and relative path. + * + * @param {string} templatePath - Template reference from Twig source. + * @param {Record} [namespaces={}] - Namespace root map. + * @returns {{ root: string, path: string }|null} Namespace lookup result. + */ +const namespaceReference = (templatePath, namespaces = {}) => { + const namespaceNames = Object.keys(namespaces); + const atNamespace = templatePath.match(/^@([^/]+)\/(.+)$/); + if (atNamespace && namespaces[atNamespace[1]]) { + return { root: namespaces[atNamespace[1]], path: atNamespace[2] }; + } + + const doubleColon = templatePath.match(/^([^:]+)::(.+)$/); + if (doubleColon && namespaces[doubleColon[1]]) { + return { root: namespaces[doubleColon[1]], path: doubleColon[2] }; + } + + const singleColon = templatePath.match(/^([^:/.]+):(.+)$/); + if (singleColon && namespaces[singleColon[1]]) { + return { root: namespaces[singleColon[1]], path: singleColon[2] }; + } + + const slashNamespace = namespaceNames.find((namespace) => + templatePath.startsWith(`${namespace}/`), + ); + if (slashNamespace) { + return { + root: namespaces[slashNamespace], + path: templatePath.slice(slashNamespace.length + 1), + }; + } + + return null; +}; + +/** + * Resolve shorthand component references against the components namespace. + * + * @param {string} templatePath - Template reference from Twig source. + * @param {string} componentRoot - Absolute component root path. + * @returns {string|null} Existing template path when found. + */ +const resolveComponentNamespaceFallback = (templatePath, componentRoot) => { + if (!componentRoot || templatePath.startsWith('.')) return null; + + const shorthandPath = + templatePath.startsWith('@') && !templatePath.includes('/') + ? templatePath.slice(1) + : templatePath; + const directComponentPath = resolveExistingFile( + fileCandidates(componentRoot, shorthandPath), + ); + if (directComponentPath) { + return directComponentPath; + } + + const genericNamespace = templatePath.match(/^@?[^/:]+[:/](.+)$/); + if (!genericNamespace) { + return null; + } + + return resolveExistingFile( + fileCandidates(componentRoot, genericNamespace[1]), + ); +}; + +/** + * Resolve a Twig include/import/extends reference from a source directory. + * + * @param {string} templatePath - Template reference from Twig source. + * @param {string} fromDir - Directory of the importing template. + * @param {{ root: string, namespaces: Record }} options - Twig plugin options. + * @returns {string|null} Existing template path when found. + */ +const resolveTwigTemplate = (templatePath, fromDir, options) => { + if (templatePath === '_self') return null; + + const namespaced = namespaceReference(templatePath, options.namespaces); + if (namespaced) { + return resolveExistingFile( + fileCandidates(namespaced.root, namespaced.path), + ); + } + + const relativeTemplate = resolveExistingFile([ + ...fileCandidates(fromDir, templatePath), + ...fileCandidates(options.root, templatePath), + ]); + + return ( + relativeTemplate || + resolveComponentNamespaceFallback( + templatePath, + options.namespaces?.components, + ) + ); +}; + +/** + * Compile a Twig template and collect its nested template references. + * + * @param {string} templateId - Twig template id. + * @param {string} filePath - Absolute template file path. + * @param {ReturnType} options - Twig plugin options. + * @returns {{ code: string, includes: string[] }} Compiled template code and references. + */ +const compileTwigTemplate = (templateId, filePath, options) => { + registerTwigExtensions(Twig); + + // Vite/Storybook can transform the same Twig module more than once during + // startup or HMR. Disable Twig.js' global duplicate-id guard while parsing. + Twig.cache(false); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const source = readFileSync(filePath, 'utf8'); + const compileOptions = { + allowInlineIncludes: true, + namespaces: options.namespaces, + rethrow: true, + ...(options.options?.compileOptions || {}), + }; + const template = Twig.twig({ + ...compileOptions, + data: source, + id: templateId, + path: filePath, + }); + const includes = unique(pluckIncludes(template.tokens).filter(Boolean)); + + return { + code: template.compile(compileOptions), + includes, + }; +}; + +/** + * Build platform-neutral Twig namespaces for the resolved project structure. + * + * @param {{ + * projectDir: string, + * srcDir: string, + * srcExists: boolean, + * structureOverrides?: boolean, + * structureRoots?: string[] + * }} env + * @returns {Record} + */ +export function makeTwigNamespaces(env) { + const structure = env.projectStructure || resolveProjectStructure(env); + if ( + structure.namespaceRoots && + typeof structure.namespaceRoots === 'object' + ) { + return { ...structure.namespaceRoots }; + } + + const { + projectDir, + srcDir, + srcExists, + structureOverrides, + structureRoots = [], + } = env; + + const namespaces = {}; + const overrideRoots = structureOverrides ? structureRoots : []; + const componentRoot = + basename(srcDir) === 'components' ? srcDir : resolve(srcDir, 'components'); + const componentsNamespace = firstExistingPath([ + ...new Set([ + ...overrideRoots, + componentRoot, + resolve(projectDir, 'src/components'), + resolve(projectDir, 'components'), + ]), + ]); + const layoutNamespace = firstExistingPath([ + ...new Set([ + ...(srcExists ? [resolve(srcDir, 'layout')] : []), + resolve(projectDir, 'src/layout'), + resolve(projectDir, 'layout'), + ]), + ]); + const tokensNamespace = firstExistingPath([ + ...new Set([ + ...(srcExists ? [resolve(srcDir, 'tokens')] : []), + resolve(projectDir, 'src/tokens'), + resolve(projectDir, 'tokens'), + ]), + ]); + + if (componentsNamespace) { + namespaces.components = componentsNamespace; + } + if (layoutNamespace) { + namespaces.layout = layoutNamespace; + } + if (tokensNamespace) { + namespaces.tokens = tokensNamespace; + } + + return namespaces; +} + +/** + * Build the generic Twig plugin options shared by Vite and Storybook. + * + * @param {{ + * projectDir: string, + * srcDir: string, + * structureOverrides?: boolean, + * structureRoots?: string[] + * }} env + * @returns {import('@vituum/vite-plugin-twig/types').PluginUserConfig} + */ +export function makeTwigPluginOptions(env) { + const { projectDir, srcDir, structureOverrides, structureRoots = [] } = env; + const structure = env.projectStructure || resolveProjectStructure(env); + const overrideRoots = structureOverrides ? structureRoots : []; + const root = firstExistingPath( + structure.twigRoots?.length + ? [...structure.twigRoots, srcDir, projectDir] + : structureOverrides + ? [...overrideRoots, srcDir, projectDir] + : [srcDir, ...overrideRoots, projectDir], + ); + + return { + root: root || srcDir || projectDir, + namespaces: makeTwigNamespaces(env), + functions: getTwigFunctionMap(), + reload: (filePath) => /\.(twig|json)$/i.test(filePath), + }; +} + +/** + * Transform Twig imports into render functions for Storybook and Vite consumers. + * + * @param {ReturnType} options - Twig options. + * @returns {import('vite').PluginOption} Twig module plugin. + */ +export function emulsifyTwigModulePlugin(options) { + const dependencyImporters = new Map(); + const addDependencyImporter = (dependency, importer) => { + const importers = dependencyImporters.get(dependency) || new Set(); + importers.add(importer); + dependencyImporters.set(dependency, importers); + }; + const clearDependencyImporter = (importer) => { + for (const importers of dependencyImporters.values()) { + importers.delete(importer); + } + }; + + return { + name: 'emulsify-twig-module', + enforce: 'pre', + transform(...args) { + const [, id] = args; + if (!isTwigModuleRequest(id)) { + return null; + } + + const filePath = stripRequestQuery(id); + const compiledIncludes = new Map(); + clearDependencyImporter(filePath); + + const compileIncludes = (includes, fromDir) => { + for (const templatePath of includes) { + const includePath = resolveTwigTemplate( + templatePath, + fromDir, + options, + ); + if (!includePath || compiledIncludes.has(includePath)) continue; + + addDependencyImporter(includePath, filePath); + this.addWatchFile(includePath); + + const compiled = compileTwigTemplate( + templatePath, + includePath, + options, + ); + compiledIncludes.set(includePath, compiled); + compileIncludes(compiled.includes, dirname(includePath)); + } + }; + + try { + const compiled = compileTwigTemplate(filePath, filePath, options); + compileIncludes(compiled.includes, dirname(filePath)); + + const includeCode = Array.from(compiledIncludes.values()) + .reverse() + .map((include) => `${include.code};`) + .join('\n'); + const renderErrorPrefix = JSON.stringify( + `An error occurred whilst rendering ${toPosixPath(filePath)}: `, + ); + const moduleCode = ` + import Twig from 'twig'; + import { registerTwigExtensions } from '@emulsify/core/extensions/twig'; + + const { twig } = Twig; + + registerTwigExtensions(Twig); + Twig.cache(false); + + ${includeCode} + + export default (context = {}) => { + try { + const template = ${compiled.code}; + template.options.allowInlineIncludes = true; + return template.render(context); + } catch (error) { + return ${renderErrorPrefix} + error.toString(); + } + }; + `; + + return { + code: moduleCode, + map: null, + }; + } catch (error) { + const message = `An error occurred whilst compiling ${toPosixPath( + filePath, + )}: ${error.toString()}`; + + return { + code: `export default () => ${JSON.stringify(message)};`, + map: null, + }; + } + }, + handleHotUpdate({ file, server }) { + if (!file.endsWith('.twig')) { + return undefined; + } + + const importers = dependencyImporters.get(file); + if (!importers?.size) { + return undefined; + } + + const modules = new Set(server.moduleGraph.getModulesByFile(file) || []); + for (const importer of importers) { + const importerModules = + server.moduleGraph.getModulesByFile(importer) || []; + + for (const module of importerModules) { + server.moduleGraph.invalidateModule(module); + modules.add(module); + } + } + + return Array.from(modules); + }, + }; +} diff --git a/config/vite/plugins/virtual-twig-globs.js b/config/vite/plugins/virtual-twig-globs.js new file mode 100644 index 0000000..4231650 --- /dev/null +++ b/config/vite/plugins/virtual-twig-globs.js @@ -0,0 +1,133 @@ +/** + * @file Virtual Twig glob map module for Storybook runtime resolution. + * + * The plugin exposes project-specific Twig template imports through a stable + * virtual module instead of replacing placeholder strings in resolver source. + */ + +import { toPosixPath } from '../utils/paths.js'; +import { unique } from '../utils/unique.js'; + +export const VIRTUAL_TWIG_GLOBS_ID = 'virtual:emulsify-twig-globs'; +const RESOLVED_VIRTUAL_TWIG_GLOBS_ID = `\0${VIRTUAL_TWIG_GLOBS_ID}`; + +/** + * @typedef {object} TwigGlobModule + * @property {Record} modules - Compiled Twig module map. + * @property {Record} sources - Raw Twig source map. + */ + +/** + * Convert an absolute project path to a Vite root-relative glob base. + * + * @param {string} projectDir - Absolute project root. + * @param {string} absolutePath - Absolute Twig root path. + * @returns {string} Vite root-relative path. + */ +function toRootRelativePath(projectDir, absolutePath) { + if (!absolutePath) return ''; + + const normalizedProjectDir = toPosixPath(projectDir || '').replace( + /\/+$/, + '', + ); + const normalizedPath = toPosixPath(absolutePath).replace(/\/+$/, ''); + + if ( + normalizedProjectDir && + normalizedPath.startsWith(`${normalizedProjectDir}/`) + ) { + return `/${normalizedPath.slice(normalizedProjectDir.length + 1)}`.replace( + /\/{2,}/g, + '/', + ); + } + + return `/${normalizedPath.replace(/^\/+/, '')}`.replace(/\/{2,}/g, '/'); +} + +/** + * Build Vite glob patterns from a resolved Emulsify environment. + * + * @param {{ projectDir?: string, projectStructure?: { twigRoots?: string[] } }} env - Emulsify environment. + * @returns {string[]} Root-relative Twig glob patterns. + */ +export function twigGlobPatterns(env) { + const roots = Array.isArray(env?.projectStructure?.twigRoots) + ? env.projectStructure.twigRoots + : []; + + return unique( + roots + .map((root) => toRootRelativePath(env?.projectDir, root)) + .filter(Boolean) + .map((root) => `${root === '/' ? '' : root}/**/*.twig`), + ); +} + +/** + * Generate the virtual module source for Twig glob maps. + * + * @param {{ projectDir?: string, projectStructure?: { twigRoots?: string[] } }} env - Emulsify environment. + * @returns {string} JavaScript module source. + */ +export function generateVirtualTwigGlobsModule(env) { + const patterns = twigGlobPatterns(env); + const globEntries = patterns.length + ? patterns + .map( + (pattern) => ` { + modules: import.meta.glob(${JSON.stringify(pattern)}, { eager: true }), + sources: import.meta.glob(${JSON.stringify(pattern)}, { eager: true, query: '?raw', import: 'default' }), + }`, + ) + .join(',\n') + : ''; + + return `/** + * Virtual module generated by config/vite/plugins/virtual-twig-globs.js. + */ + +const mergeGlobMaps = (groups) => + groups.reduce( + (merged, group) => ({ + modules: { ...merged.modules, ...group.modules }, + sources: { ...merged.sources, ...group.sources }, + }), + { modules: {}, sources: {} }, + ); + +const globMaps = mergeGlobMaps([ +${globEntries} +]); + +export const modules = globMaps.modules; +export const sources = globMaps.sources; +`; +} + +/** + * Provide `virtual:emulsify-twig-globs` for Storybook Twig runtime helpers. + * + * @param {{ projectDir?: string, projectStructure?: { twigRoots?: string[] } }} env - Emulsify environment. + * @returns {import('vite').PluginOption} Virtual module plugin. + */ +export function virtualTwigGlobsPlugin(env) { + return { + name: 'emulsify-virtual-twig-globs', + resolveId(id) { + if (id === VIRTUAL_TWIG_GLOBS_ID) { + return RESOLVED_VIRTUAL_TWIG_GLOBS_ID; + } + + return null; + }, + load(id) { + if (id === RESOLVED_VIRTUAL_TWIG_GLOBS_ID) { + return generateVirtualTwigGlobsModule(env); + } + + return null; + }, + }; +} diff --git a/config/vite/plugins/virtual-twig-globs.test.js b/config/vite/plugins/virtual-twig-globs.test.js new file mode 100644 index 0000000..3787966 --- /dev/null +++ b/config/vite/plugins/virtual-twig-globs.test.js @@ -0,0 +1,51 @@ +/** + * @file Tests for the Twig glob virtual module plugin. + */ + +import { + generateVirtualTwigGlobsModule, + VIRTUAL_TWIG_GLOBS_ID, + virtualTwigGlobsPlugin, +} from './virtual-twig-globs.js'; + +const env = { + projectDir: '/project', + projectStructure: { + twigRoots: ['/project/src/components', '/project/src/layout'], + }, +}; + +describe('virtual Twig glob module plugin', () => { + it('resolves and loads the virtual module', () => { + const plugin = virtualTwigGlobsPlugin(env); + const resolvedId = plugin.resolveId(VIRTUAL_TWIG_GLOBS_ID); + + expect(resolvedId).toBe('\0virtual:emulsify-twig-globs'); + expect(plugin.resolveId('/real/module.js')).toBeNull(); + expect(plugin.load(resolvedId)).toContain( + 'export const modules = globMaps.modules;', + ); + expect(plugin.load('/real/module.js')).toBeNull(); + }); + + it('generates named exports from resolved Twig roots', () => { + const source = generateVirtualTwigGlobsModule(env); + + expect(source).toContain('const globMaps = mergeGlobMaps(['); + expect(source.match(/mergeGlobMaps\(\[/g)).toHaveLength(1); + expect(source).toContain( + 'modules: import.meta.glob("/src/components/**/*.twig", { eager: true })', + ); + expect(source).toContain( + 'modules: import.meta.glob("/src/layout/**/*.twig", { eager: true })', + ); + expect(source).toMatch( + /sources: import\.meta\.glob\("\/src\/components\/\*\*\/\*\.twig", \{ eager: true, query: '\?raw', import: 'default' \}\)/, + ); + expect(source).toMatch( + /sources: import\.meta\.glob\("\/src\/layout\/\*\*\/\*\.twig", \{ eager: true, query: '\?raw', import: 'default' \}\)/, + ); + expect(source).toContain('export const modules = globMaps.modules;'); + expect(source).toContain('export const sources = globMaps.sources;'); + }); +}); diff --git a/config/vite/plugins/vituum-patch.js b/config/vite/plugins/vituum-patch.js new file mode 100644 index 0000000..da7590b --- /dev/null +++ b/config/vite/plugins/vituum-patch.js @@ -0,0 +1,165 @@ +/** + * @file Vituum Twig plugin adapter for Emulsify Vite builds. + * + * Emulsify keeps Vituum's Twig rendering, middleware, and reload behavior while + * removing incompatible page-entry rename hooks from Vite build output. + */ + +import twig from '@vituum/vite-plugin-twig'; +import Twig from 'twig'; + +import { registerTwigExtensions } from '../../../src/extensions/twig/index.js'; +import { makeTwigPluginOptions } from './twig-module.js'; + +const EXPECTED_PLUGIN_NAMES = [ + '@vituum/vite-plugin-core:bundle', + '@vituum/vite-plugin-twig', +]; +const EXPECTED_HOOKS_TO_STRIP = ['buildStart', 'buildEnd']; +const VITUUM_TWIG_PLUGIN_NAME = '@vituum/vite-plugin-twig'; +const SHAPE_CHANGE_GUIDANCE = + 'Pin @vituum/vite-plugin-twig to a known-good version or update vituum-patch.js.'; + +/** + * Inspect Vituum plugin output before patching so shape changes fail loudly. + * + * @param {import('vite').PluginOption[]} plugins - Normalized Vituum plugins. + * @returns {{ + * detectedPluginNames: string[], + * foundPluginNames: Set, + * twigHooksPresent: Set + * }} Detected plugin shape details. + */ +function inspectVituumPluginShape(plugins) { + const detectedPluginNames = []; + const foundPluginNames = new Set(); + const twigHooksPresent = new Set(); + + for (const pluginOption of plugins) { + const pluginName = pluginOption?.name; + detectedPluginNames.push(pluginName || ''); + + if (EXPECTED_PLUGIN_NAMES.includes(pluginName)) { + foundPluginNames.add(pluginName); + } + + if (pluginName === VITUUM_TWIG_PLUGIN_NAME) { + for (const hookName of EXPECTED_HOOKS_TO_STRIP) { + if (hookName in pluginOption) { + twigHooksPresent.add(hookName); + } + } + } + } + + return { detectedPluginNames, foundPluginNames, twigHooksPresent }; +} + +/** + * Format plugin names for shape-change diagnostics. + * + * @param {string[]} pluginNames - Plugin names to report. + * @returns {string} JSON-formatted plugin list. + */ +function formatPluginNames(pluginNames) { + return JSON.stringify(pluginNames); +} + +/** + * Assert Vituum exposed the plugin names and hooks Emulsify patches. + * + * @param {ReturnType} shape - Detected shape. + */ +function assertExpectedVituumShape(shape) { + const missingPluginNames = EXPECTED_PLUGIN_NAMES.filter( + (pluginName) => !shape.foundPluginNames.has(pluginName), + ); + + if (missingPluginNames.length) { + throw new Error( + [ + `Vituum plugin shape changed: expected ${missingPluginNames + .map((pluginName) => `'${pluginName}'`) + .join(', ')} not found.`, + `Detected plugins: ${formatPluginNames(shape.detectedPluginNames)}.`, + SHAPE_CHANGE_GUIDANCE, + ].join(' '), + ); + } + + if (!shape.twigHooksPresent.size) { + throw new Error( + [ + `Vituum plugin shape changed: '${VITUUM_TWIG_PLUGIN_NAME}' did not expose any targeted hooks to strip.`, + `Expected at least one of: ${formatPluginNames(EXPECTED_HOOKS_TO_STRIP)}.`, + `Detected plugins: ${formatPluginNames(shape.detectedPluginNames)}.`, + SHAPE_CHANGE_GUIDANCE, + ].join(' '), + ); + } +} + +/** + * Assert stripped Vituum hooks are absent after patching. + * + * @param {import('vite').PluginOption} pluginOption - Patched plugin. + */ +function assertHooksStripped(pluginOption) { + const remainingHooks = EXPECTED_HOOKS_TO_STRIP.filter( + (hookName) => hookName in pluginOption, + ); + + if (remainingHooks.length) { + throw new Error( + [ + `Vituum plugin patch failed: '${VITUUM_TWIG_PLUGIN_NAME}' still exposes targeted hooks after stripping.`, + `Remaining hooks: ${formatPluginNames(remainingHooks)}.`, + SHAPE_CHANGE_GUIDANCE, + ].join(' '), + ); + } +} + +/** + * Strip the Vituum hooks that conflict with Emulsify build output. + * + * @param {import('vite').PluginOption} pluginOption - Cloned Twig plugin. + */ +function stripExpectedHooks(pluginOption) { + delete pluginOption.buildStart; + delete pluginOption.buildEnd; +} + +/** + * Instantiate Vituum's Twig renderer without its entry-renaming build hooks. + * + * @param {Parameters[0]} env - Project environment. + * @param {ReturnType} [options] - Twig plugin options. + * @returns {import('vite').PluginOption[]} Vituum Twig plugin options. + */ +export function makeTwigPlugins(env, options = makeTwigPluginOptions(env)) { + registerTwigExtensions(Twig); + + const twigPlugins = twig(options); + const normalizedPlugins = Array.isArray(twigPlugins) + ? twigPlugins + : [twigPlugins]; + const shape = inspectVituumPluginShape(normalizedPlugins); + assertExpectedVituumShape(shape); + + return normalizedPlugins + .filter( + (pluginOption) => + pluginOption?.name !== '@vituum/vite-plugin-core:bundle', + ) + .map((pluginOption) => { + if (pluginOption?.name !== '@vituum/vite-plugin-twig') { + return pluginOption; + } + + const renderPlugin = { ...pluginOption }; + stripExpectedHooks(renderPlugin); + assertHooksStripped(renderPlugin); + return renderPlugin; + }); +} diff --git a/config/vite/plugins/yaml-module.js b/config/vite/plugins/yaml-module.js new file mode 100644 index 0000000..43acf6a --- /dev/null +++ b/config/vite/plugins/yaml-module.js @@ -0,0 +1,133 @@ +/** + * @file YAML module plugin for Vite imports. + * + * This plugin turns YAML imports into ESM modules with default exports and safe + * named exports for valid top-level keys. + */ + +import { load as loadYaml } from 'js-yaml'; + +/** + * Remove the Vite query string from a module id. + * + * @param {string} id - Vite module id. + * @returns {string} Filesystem path without query parameters. + */ +const stripRequestQuery = (id) => id.split('?')[0]; + +/** + * Determine whether a Vite request should compile as a YAML module. + * + * @param {string} id - Vite module id, including an optional query string. + * @returns {boolean} TRUE when the request is a YAML data import. + */ +const isYamlModuleRequest = (id) => { + const [filePath, query = ''] = id.split('?'); + if (!/\.ya?ml$/i.test(filePath)) return false; + return !/(^|&)(raw|url)\b/.test(query); +}; + +const reservedYamlExportIdentifiers = new Set([ + 'await', + 'break', + 'case', + 'catch', + 'class', + 'const', + 'continue', + 'debugger', + 'default', + 'delete', + 'do', + 'else', + 'export', + 'extends', + 'finally', + 'for', + 'function', + 'if', + 'import', + 'in', + 'instanceof', + 'let', + 'new', + 'return', + 'super', + 'switch', + 'this', + 'throw', + 'try', + 'typeof', + 'var', + 'void', + 'while', + 'with', + 'yield', +]); + +/** + * Determine whether a YAML key can be emitted as a named ESM export. + * + * @param {string} key - Top-level YAML object key. + * @returns {boolean} TRUE when the key is safe to emit as a named export. + */ +const isValidYamlExportIdentifier = (key) => + /^[A-Za-z_$][0-9A-Za-z_$]*$/.test(key) && + !key.startsWith('$') && + !reservedYamlExportIdentifiers.has(key); + +/** + * Determine whether a parsed YAML value is a plain object. + * + * @param {*} value - Parsed YAML value. + * @returns {boolean} TRUE when the value is a plain object. + */ +const isPlainObject = (value) => + value !== null && + typeof value === 'object' && + !Array.isArray(value) && + [Object.prototype, null].includes(Object.getPrototypeOf(value)); + +/** + * Transform YAML imports into JavaScript modules. + * + * @returns {import('vite').PluginOption} YAML module plugin. + */ +export function yamlModulePlugin() { + return { + name: 'emulsify-yaml', + enforce: 'pre', + transform(source, id) { + if (!isYamlModuleRequest(id)) { + return null; + } + + try { + const data = loadYaml(source) ?? null; + const namedExports = isPlainObject(data) + ? Object.entries(data) + .filter(([key]) => isValidYamlExportIdentifier(key)) + .map( + ([key, value]) => + `export const ${key} = ${JSON.stringify(value)};`, + ) + .join('\n') + : ''; + const defaultExport = `export default ${JSON.stringify(data)};`; + + return { + code: `${namedExports}${namedExports ? '\n' : ''}${defaultExport}\n`, + map: null, + }; + } catch (error) { + this.error( + `Unable to parse YAML module ${stripRequestQuery(id)}: ${ + error?.message || error + }`, + ); + } + + return null; + }, + }; +} diff --git a/config/vite/project-config.js b/config/vite/project-config.js new file mode 100644 index 0000000..81fd383 --- /dev/null +++ b/config/vite/project-config.js @@ -0,0 +1,148 @@ +/** + * @file Normalized project configuration for Emulsify Vite and Storybook. + * + * This module is the single Node-side reader for `project.emulsify.json`. + * Validation is intentionally permissive so existing projects can upgrade + * without reshaping older config files. + */ + +import { normalize, resolve, sep } from 'path'; +import { getPlatformAdapter } from './platforms.js'; +import { resolveProjectStructure } from './project-structure.js'; +import { safeExists, safeReadJson } from './utils/fs-safe.js'; + +/** + * Ensure an absolute path stays inside the project directory. + * + * @param {string} projectDir - Absolute project root. + * @param {string} candidate - Path to validate (absolute or relative). + * @returns {string|null} A safe absolute path, or null if outside projectDir. + */ +export function coerceToProjectPath(projectDir, candidate) { + if (typeof candidate !== 'string' || !candidate.trim()) return null; + + const absProject = resolve(projectDir); + const absCandidate = resolve(projectDir, candidate); + const inProject = + absCandidate.startsWith(absProject + sep) || absCandidate === absProject; + return inProject ? absCandidate : null; +} + +/** + * Normalize config strings to lowercase identifiers. + * + * @param {*} value - Candidate value. + * @returns {string} Normalized string. + */ +function normalizeIdentifier(value) { + return (value || '').toString().toLowerCase().trim(); +} + +/** + * Normalize variant structure implementation declarations. + * + * @param {string} projectDir - Absolute project root. + * @param {Array} implementations - Raw implementation entries. + * @returns {{name: string, directory: string}[]} Safe implementation entries. + */ +function normalizeStructureImplementations(projectDir, implementations = []) { + if (!Array.isArray(implementations)) return []; + + return implementations + .map((item, index) => { + const rawDirectory = + typeof item?.directory === 'string' ? item.directory : null; + const directory = rawDirectory + ? coerceToProjectPath(projectDir, rawDirectory) + : null; + if (!directory) return null; + + const name = + typeof item?.name === 'string' && item.name.trim() + ? normalizeIdentifier(item.name) + : `structure-${index + 1}`; + + return { + name, + directory: normalize(directory), + }; + }) + .filter(Boolean); +} + +/** + * Normalize project config for current tooling consumers. + * + * @param {string} [projectDir=process.cwd()] - Absolute project root. + * @param {NodeJS.ProcessEnv|Record} [env=process.env] - Environment values. + * @returns {object} Normalized Emulsify environment/config model. + */ +export function resolveProjectConfig( + projectDir = process.cwd(), + env = process.env, +) { + const root = resolve(projectDir); + const configPath = coerceToProjectPath(root, 'project.emulsify.json'); + const rawConfigResult = configPath ? safeReadJson(configPath) : {}; + const rawConfig = + rawConfigResult?.data && typeof rawConfigResult.data === 'object' + ? rawConfigResult.data + : {}; + + const srcCandidate = resolve(root, 'src'); + const srcExists = safeExists(srcCandidate); + const srcDir = srcExists ? srcCandidate : resolve(root, 'components'); + + const platform = + normalizeIdentifier(env.EMULSIFY_PLATFORM) || + normalizeIdentifier(rawConfig?.project?.platform) || + normalizeIdentifier(rawConfig?.variant?.platform) || + 'generic'; + const platformAdapter = getPlatformAdapter(platform); + + const singleDirectoryComponents = Boolean( + rawConfig?.project?.singleDirectoryComponents, + ); + const rawStructureImplementations = + rawConfig?.variant?.structureImplementations; + const structureImplementations = normalizeStructureImplementations( + root, + rawStructureImplementations, + ); + const structureRoots = structureImplementations.map( + (implementation) => implementation.directory, + ); + const projectStructure = resolveProjectStructure({ + projectDir: root, + srcDir, + srcExists, + SDC: singleDirectoryComponents, + structureImplementations, + platformAdapter, + }); + + return { + projectDir: root, + platform, + machineName: + typeof rawConfig?.project?.machineName === 'string' + ? rawConfig.project.machineName + : undefined, + srcExists, + srcDir, + singleDirectoryComponents, + SDC: singleDirectoryComponents, + structureOverrides: projectStructure.structureOverrides, + structureImplementations, + structureRoots, + componentRoots: projectStructure.componentRoots, + globalRoots: projectStructure.globalRoots, + namespaceRoots: projectStructure.namespaceRoots, + outputStrategy: platformAdapter.outputStrategy, + outputMode: platformAdapter.outputStrategy, + projectStructure, + platformAdapter, + adapter: platformAdapter, + projectConfig: rawConfig, + }; +} diff --git a/config/vite/project-config.test.js b/config/vite/project-config.test.js new file mode 100644 index 0000000..562ce57 --- /dev/null +++ b/config/vite/project-config.test.js @@ -0,0 +1,221 @@ +/** + * @file Tests for normalized Emulsify project configuration. + */ + +import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'fs'; +import { join } from 'path'; +import { tmpdir } from 'os'; +import { resolveProjectConfig } from './project-config.js'; + +const makeTempProject = () => mkdtempSync(join(tmpdir(), 'emulsify-core-')); + +const writeProjectConfig = (projectDir, config) => { + writeFileSync( + join(projectDir, 'project.emulsify.json'), + JSON.stringify(config, null, 2), + ); +}; + +describe('resolveProjectConfig', () => { + let projectDir; + + afterEach(() => { + if (projectDir) { + rmSync(projectDir, { recursive: true, force: true }); + } + }); + + it('normalizes Drupal project config with SDC enabled', () => { + projectDir = makeTempProject(); + mkdirSync(join(projectDir, 'src/components'), { recursive: true }); + writeProjectConfig(projectDir, { + project: { + platform: 'drupal', + name: 'whisk', + machineName: 'whisk', + singleDirectoryComponents: true, + }, + }); + + const env = resolveProjectConfig(projectDir, {}); + + expect(env).toMatchObject({ + projectDir, + platform: 'drupal', + machineName: 'whisk', + srcExists: true, + srcDir: join(projectDir, 'src'), + singleDirectoryComponents: true, + SDC: true, + structureOverrides: false, + outputStrategy: 'drupal-sdc', + outputMode: 'drupal-sdc', + }); + expect(env.componentRoots).toEqual([join(projectDir, 'src/components')]); + expect(env.namespaceRoots.components).toBe( + join(projectDir, 'src/components'), + ); + expect(env.projectStructure).toMatchObject({ + componentRoots: [join(projectDir, 'src/components')], + globalRoots: [join(projectDir, 'src')], + storyRoots: [join(projectDir, 'src')], + mirrorComponentOutput: true, + }); + expect(env.platformAdapter).toMatchObject({ + name: 'drupal', + storybook: { + loadDrupalBehaviorShim: true, + attachDrupalBehaviors: true, + registerDrupalTwigFilters: true, + }, + build: { + mirrorDistComponentsToRoot: true, + }, + }); + }); + + it('normalizes generic project config without platform-specific behavior', () => { + projectDir = makeTempProject(); + mkdirSync(join(projectDir, 'components'), { recursive: true }); + writeProjectConfig(projectDir, { + project: { + platform: 'generic', + name: 'starter', + machineName: 'starter', + }, + }); + + const env = resolveProjectConfig(projectDir, {}); + + expect(env).toMatchObject({ + platform: 'generic', + machineName: 'starter', + srcExists: false, + srcDir: join(projectDir, 'components'), + singleDirectoryComponents: false, + SDC: false, + outputStrategy: 'dist', + }); + expect(env.platformAdapter).toMatchObject({ + name: 'generic', + storybook: { + loadDrupalBehaviorShim: false, + attachDrupalBehaviors: false, + registerDrupalTwigFilters: false, + }, + build: { + mirrorDistComponentsToRoot: false, + }, + }); + expect(env.projectStructure).toMatchObject({ + componentRoots: [join(projectDir, 'components')], + globalRoots: [], + storyRoots: [join(projectDir, 'components')], + mirrorComponentOutput: false, + }); + }); + + it('normalizes multiple named variant structure implementations', () => { + projectDir = makeTempProject(); + for (const directory of [ + 'src/components', + 'src/foundation', + 'src/layout', + 'src/tokens', + ]) { + mkdirSync(join(projectDir, directory), { recursive: true }); + } + writeProjectConfig(projectDir, { + project: { + platform: 'drupal', + name: 'emulsify-ui-kit', + machineName: 'emulsify-ui-kit', + }, + variant: { + platform: 'drupal', + structureImplementations: [ + { name: 'components', directory: './src/components/' }, + { name: 'foundation', directory: './src/foundation/' }, + { name: 'layout', directory: './src/layout/' }, + { name: 'tokens', directory: './src/tokens/' }, + ], + }, + }); + + const env = resolveProjectConfig(projectDir, {}); + const expectedRoots = [ + join(projectDir, 'src/components'), + join(projectDir, 'src/foundation'), + join(projectDir, 'src/layout'), + join(projectDir, 'src/tokens'), + ]; + + expect(env.structureOverrides).toBe(true); + expect(env.structureImplementations).toEqual([ + { name: 'components', directory: expectedRoots[0] }, + { name: 'foundation', directory: expectedRoots[1] }, + { name: 'layout', directory: expectedRoots[2] }, + { name: 'tokens', directory: expectedRoots[3] }, + ]); + expect(env.structureRoots).toEqual(expectedRoots); + expect(env.componentRoots).toEqual(expectedRoots); + expect(env.namespaceRoots).toEqual({ + components: expectedRoots[0], + foundation: expectedRoots[1], + layout: expectedRoots[2], + tokens: expectedRoots[3], + }); + expect(env.projectStructure.storyRoots).toEqual(expectedRoots); + }); + + it('lets EMULSIFY_PLATFORM override project and variant platform config', () => { + projectDir = makeTempProject(); + writeProjectConfig(projectDir, { + project: { + platform: 'drupal', + machineName: 'override-test', + }, + variant: { + platform: 'drupal', + }, + }); + + const env = resolveProjectConfig(projectDir, { + EMULSIFY_PLATFORM: 'generic', + }); + + expect(env.platform).toBe('generic'); + expect(env.platformAdapter.name).toBe('generic'); + expect(env.platformAdapter.build.mirrorDistComponentsToRoot).toBe(false); + }); + + it('ignores unsafe structure implementation paths', () => { + projectDir = makeTempProject(); + mkdirSync(join(projectDir, 'src/components'), { recursive: true }); + writeProjectConfig(projectDir, { + project: { + platform: 'generic', + }, + variant: { + structureImplementations: [ + { name: 'unsafeRelative', directory: '../outside' }, + { name: 'unsafeAbsolute', directory: '/tmp/outside' }, + { name: 'components', directory: './src/components' }, + ], + }, + }); + + const env = resolveProjectConfig(projectDir, {}); + + expect(env.structureImplementations).toEqual([ + { + name: 'components', + directory: join(projectDir, 'src/components'), + }, + ]); + expect(env.structureRoots).toEqual([join(projectDir, 'src/components')]); + expect(env.namespaceRoots).toEqual({ + components: join(projectDir, 'src/components'), + }); + }); +}); diff --git a/config/vite/project-extensions.js b/config/vite/project-extensions.js new file mode 100644 index 0000000..ebfa364 --- /dev/null +++ b/config/vite/project-extensions.js @@ -0,0 +1,177 @@ +/** + * @file Project-level Vite extension loader. + * + * Loads optional project-level Vite plugin extensions from: + * config/emulsify-core/vite/plugins.(mjs|js|cjs) + * + * Supported shapes in that file: + * 1) export default [vitePlugin(), ...] + * 2) export default (ctx) => [vitePlugin(), ...] + * 3) module.exports = [ ... ] + * 4) export const extendConfig = (config, ctx) => patchObject + */ + +import { isAbsolute, normalize, relative, resolve } from 'path'; +import { pathToFileURL } from 'url'; +import { createRequire } from 'module'; +import { firstExistingPath } from './utils/fs-safe.js'; + +const extensionCandidates = [ + 'config/emulsify-core/vite/plugins.mjs', + 'config/emulsify-core/vite/plugins.js', + 'config/emulsify-core/vite/plugins.cjs', +]; + +/** + * Normalize CommonJS module results into an ESM-like shape. + * + * @param {*} mod - Required module result. + * @returns {object} Module namespace-like object. + */ +function cjsModule(mod) { + return mod && typeof mod === 'object' ? mod : { default: mod }; +} + +/** + * Determine whether a failed CommonJS load should retry as native ESM. + * + * @param {Error} error - CommonJS load error. + * @returns {boolean} TRUE when native import should handle the module. + */ +function shouldImportAsEsm(error) { + return ( + ['ERR_REQUIRE_ESM', 'ERR_REQUIRE_ASYNC_MODULE'].includes(error?.code) || + /Cannot use import statement outside a module|Unexpected token 'export'|Unexpected token export/.test( + error?.message || '', + ) + ); +} + +/** + * Resolve the consuming project root for project-level extensions. + * + * @param {object} ctx - Context passed to project plugin factories. + * @returns {string} Absolute path. + */ +function projectRoot(ctx = {}) { + return resolve(ctx?.env?.projectDir || process.cwd()); +} + +/** + * Resolve a path inside the consuming project root. + * + * @param {string} root - Absolute project root. + * @param {string} rel - Project-relative path. + * @returns {string} Absolute path. + */ +function inProject(root, rel) { + return resolve(root, rel); +} + +/** + * Determine whether an absolute path stays inside the consuming project root. + * + * @param {string} root - Absolute project root. + * @param {string} abs - Absolute path to inspect. + * @returns {boolean} TRUE when the path is under the project root. + */ +function insideProject(root, abs) { + const target = normalize(abs); + const rel = relative(root, target); + return Boolean(rel) && !rel.startsWith('..') && !isAbsolute(rel); +} + +/** + * Load an ESM or CJS module from an absolute path. + * + * @param {string|null} absPath - Absolute module path. + * @returns {Promise} Module namespace or null. + */ +async function loadModule(absPath) { + if (!absPath) return null; + const req = createRequire(absPath); + + if (absPath.endsWith('.cjs')) { + return cjsModule(req(absPath)); + } + + if (absPath.endsWith('.js')) { + try { + return cjsModule(req(absPath)); + } catch (error) { + if (!shouldImportAsEsm(error)) { + throw error; + } + } + } + + return import(pathToFileURL(absPath).href); +} + +/** + * Normalize CJS and ESM default export shapes. + * + * @param {object|null} mod - Loaded module namespace. + * @returns {*} Supported default export shape. + */ +function defaultExport(mod) { + const raw = mod?.default ?? mod; + if ( + raw && + typeof raw === 'object' && + (Array.isArray(raw.default) || typeof raw.default === 'function') + ) { + return raw.default; + } + return raw; +} + +/** + * Normalize named ESM and CJS object exports for extendConfig. + * + * @param {object|null} mod - Loaded module namespace. + * @returns {Function|undefined} Project config patcher, when present. + */ +function extendConfigExport(mod) { + if (typeof mod?.extendConfig === 'function') { + return mod.extendConfig; + } + if (typeof mod?.default?.extendConfig === 'function') { + return mod.default.extendConfig; + } + return undefined; +} + +/** + * Load user-supplied plugins and an optional config patcher. + * + * @param {object} ctx - Context passed to project plugin factories. + * @returns {Promise<{ projectPlugins: import('vite').PluginOption[], extendConfig?: Function }>} + */ +export async function loadProjectExtensions(ctx = {}) { + const root = projectRoot(ctx); + const candidate = + firstExistingPath( + extensionCandidates + .map((candidatePath) => inProject(root, candidatePath)) + .filter((candidatePath) => insideProject(root, candidatePath)), + ) || null; + + if (!candidate) return { projectPlugins: [] }; + + const mod = await loadModule(candidate); + + // Normalize supported default export shapes into a plugin array. + let projectPlugins = []; + const raw = defaultExport(mod); + if (Array.isArray(raw)) { + projectPlugins = raw; + } else if (typeof raw === 'function') { + projectPlugins = raw(ctx) || []; + } + + // Named extendConfig export lets projects patch the assembled Vite config. + const extendConfig = extendConfigExport(mod); + + return { projectPlugins, extendConfig }; +} diff --git a/config/vite/project-extensions.test.js b/config/vite/project-extensions.test.js new file mode 100644 index 0000000..9e3c5cb --- /dev/null +++ b/config/vite/project-extensions.test.js @@ -0,0 +1,225 @@ +/** + * @file Tests for project-level Vite extension loading. + */ + +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'fs'; +import { tmpdir } from 'os'; +import { join } from 'path'; +import { spawnSync } from 'child_process'; +import { pathToFileURL } from 'url'; + +import { loadProjectExtensions } from './project-extensions.js'; + +const makeTempProject = () => mkdtempSync(join(tmpdir(), 'emulsify-core-')); + +const extensionDir = (projectDir) => + join(projectDir, 'config/emulsify-core/vite'); + +const writeExtension = (projectDir, fileName, source) => { + const dir = extensionDir(projectDir); + mkdirSync(dir, { recursive: true }); + writeFileSync(join(dir, fileName), source); +}; + +const loadExtensions = (projectDir, env = {}) => + loadProjectExtensions({ + env: { + projectDir, + machineName: 'fixture-project', + ...env, + }, + }); + +const loadExtensionsWithNativeNode = (projectDir, env, resultExpression) => { + const loaderUrl = pathToFileURL( + join(process.cwd(), 'config/vite/project-extensions.js'), + ).href; + const projectEnv = { + projectDir, + ...env, + }; + const result = spawnSync( + process.execPath, + [ + '--input-type=module', + '-e', + ` +import { loadProjectExtensions } from ${JSON.stringify(loaderUrl)}; + +const result = await loadProjectExtensions({ env: ${JSON.stringify(projectEnv)} }); +console.log(JSON.stringify(${resultExpression})); +`, + ], + { encoding: 'utf8' }, + ); + + if (result.status !== 0) { + throw new Error(result.stderr || result.stdout); + } + + return JSON.parse(result.stdout); +}; + +describe('loadProjectExtensions', () => { + let projectDir; + + beforeEach(() => { + projectDir = makeTempProject(); + }); + + afterEach(() => { + if (projectDir) { + rmSync(projectDir, { recursive: true, force: true }); + } + }); + + it('loads and uses config/emulsify-core/vite/plugins.js from the project root', async () => { + writeExtension( + projectDir, + 'plugins.js', + ` +module.exports = [ + { + name: 'project-js-plugin', + config() { + return { define: { __PROJECT_JS_PLUGIN__: JSON.stringify(true) } }; + }, + }, +]; +`, + ); + + const { projectPlugins } = await loadExtensions(projectDir); + + expect(projectPlugins).toHaveLength(1); + expect(projectPlugins[0].name).toBe('project-js-plugin'); + expect(projectPlugins[0].config()).toEqual({ + define: { __PROJECT_JS_PLUGIN__: 'true' }, + }); + }); + + it('passes env to ESM default plugin factories', async () => { + writeExtension( + projectDir, + 'plugins.mjs', + ` +export default ({ env }) => [ + { + name: \`project-factory-\${env.machineName}\`, + }, +]; +`, + ); + + const projectPlugins = loadExtensionsWithNativeNode( + projectDir, + { machineName: 'env-aware' }, + 'result.projectPlugins', + ); + + expect(projectPlugins).toEqual([{ name: 'project-factory-env-aware' }]); + }); + + it('supports ESM config/emulsify-core/vite/plugins.js in module projects', async () => { + writeFileSync( + join(projectDir, 'package.json'), + JSON.stringify({ type: 'module' }), + ); + writeExtension( + projectDir, + 'plugins.js', + ` +export default [ + { + name: 'project-esm-js-plugin', + }, +]; +`, + ); + + const projectPlugins = loadExtensionsWithNativeNode( + projectDir, + { machineName: 'esm-js' }, + 'result.projectPlugins', + ); + + expect(projectPlugins).toEqual([{ name: 'project-esm-js-plugin' }]); + }); + + it('supports CommonJS module exports', async () => { + writeExtension( + projectDir, + 'plugins.cjs', + ` +module.exports = [{ name: 'project-cjs-module-export' }]; +`, + ); + + const { projectPlugins } = await loadExtensions(projectDir); + + expect(projectPlugins).toEqual([{ name: 'project-cjs-module-export' }]); + }); + + it('supports CommonJS default exports', async () => { + writeExtension( + projectDir, + 'plugins.cjs', + ` +exports.default = ({ env }) => [ + { + name: \`project-cjs-default-\${env.machineName}\`, + }, +]; +`, + ); + + const { projectPlugins } = await loadExtensions(projectDir, { + machineName: 'default-export', + }); + + expect(projectPlugins).toEqual([ + { name: 'project-cjs-default-default-export' }, + ]); + }); + + it('loads named extendConfig exports', async () => { + writeExtension( + projectDir, + 'plugins.mjs', + ` +export const extendConfig = (config, { env }) => ({ + define: { + __BASE__: JSON.stringify(config.base), + __PROJECT_NAME__: JSON.stringify(env.machineName), + }, +}); +`, + ); + + const result = loadExtensionsWithNativeNode( + projectDir, + { machineName: 'extended-project' }, + `{ + projectPlugins: result.projectPlugins, + extended: result.extendConfig({ base: '/storybook/' }, { + env: { machineName: 'extended-project' }, + }), + }`, + ); + + expect(result.projectPlugins).toEqual([]); + expect(result.extended).toEqual({ + define: { + __BASE__: '"/storybook/"', + __PROJECT_NAME__: '"extended-project"', + }, + }); + }); + + it('returns empty extensions when no public project extension file exists', async () => { + const { projectPlugins, extendConfig } = await loadExtensions(projectDir); + + expect(projectPlugins).toEqual([]); + expect(extendConfig).toBeUndefined(); + }); +}); diff --git a/config/vite/project-structure.js b/config/vite/project-structure.js new file mode 100644 index 0000000..3b222b9 --- /dev/null +++ b/config/vite/project-structure.js @@ -0,0 +1,401 @@ +/** + * @file Shared component structure and output path resolution. + * + * The helpers here keep source-root discovery, Rollup entry keys, copied asset + * destinations, Twig namespaces, and Storybook roots aligned. + */ + +import { basename, relative, resolve, sep } from 'path'; +import { safeExists } from './utils/fs-safe.js'; +import { replaceLastSlash, toPosixPath } from './utils/paths.js'; +import { unique } from './utils/unique.js'; + +export { replaceLastSlash, toPosixPath }; + +/** Strip a JS or SCSS extension from an output key. */ +const stripAssetExtension = (filePath) => filePath.replace(/\.(scss|js)$/i, ''); + +/** Insert "/css|js" bucket unless SDC=true; strip extension. */ +export function injectBucket(rel, bucket, SDC) { + const withoutExt = stripAssetExtension(rel); + if (SDC) { + return bucket === 'css' ? `${withoutExt}__style` : withoutExt; + } + return replaceLastSlash(rel, `/${bucket}/`).replace(/\.(scss|js)$/i, ''); +} + +/** + * Relativize an absolute path from a base directory using POSIX separators. + * + * @param {string} absPath - Absolute file path. + * @param {string} baseDir - Absolute base directory. + * @returns {string} POSIX relative path. + */ +export function relativeFrom(absPath, baseDir) { + return toPosixPath(relative(baseDir, absPath)); +} + +/** + * Determine whether a file is inside a source root. + * + * @param {string} absPath - Absolute file path. + * @param {string} rootDir - Absolute root path. + * @returns {boolean} TRUE when the file is inside the root. + */ +function isInsideRoot(absPath, rootDir) { + const rel = relative(rootDir, absPath); + return Boolean(rel) && !rel.startsWith('..') && !rel.includes(`..${sep}`); +} + +/** + * Determine whether a path is the same as a root or inside it. + * + * @param {string} absPath - Absolute file path. + * @param {string} rootDir - Absolute root path. + * @returns {boolean} TRUE when the path is inside or equal to the root. + */ +function isSameOrInsideRoot(absPath, rootDir) { + return absPath === rootDir || isInsideRoot(absPath, rootDir); +} + +/** + * Find the first source root containing a file. + * + * @param {string} absPath - Absolute file path. + * @param {{name: string, directory: string}[]} roots - Source root records. + * @returns {{name: string, directory: string}|null} Matching root record. + */ +export function findSourceRoot(absPath, roots = []) { + return roots.find((root) => isInsideRoot(absPath, root.directory)) || null; +} + +/** + * Build fallback component roots for non-variant projects. + * + * The recommended `src/components` root wins when present. If a project has a + * `src/` directory but no `src/components`, root `./components` remains a valid + * canonical component source for upgrades. + * + * @param {{projectDir: string, srcDir: string, srcExists: boolean}} env + * @returns {{name: string, directory: string}[]} Component source roots. + */ +function fallbackComponentRoots({ projectDir, srcDir, srcExists }) { + const primary = + basename(srcDir) === 'components' ? srcDir : resolve(srcDir, 'components'); + const rootComponents = resolve(projectDir, 'components'); + const candidates = unique( + [primary, ...(srcExists ? [rootComponents] : []), rootComponents].filter( + Boolean, + ), + ); + const selected = candidates.find(safeExists) || primary; + + return [{ name: 'components', directory: selected }]; +} + +/** + * Build fallback global roots for non-variant projects. + * + * @param {{srcDir: string, srcExists: boolean}} env - Project environment. + * @returns {{name: string, directory: string}[]} Global source roots. + */ +function fallbackGlobalRoots({ srcDir, srcExists }) { + return srcExists ? [{ name: 'global', directory: srcDir }] : []; +} + +/** + * Build Twig namespace roots for explicit structure implementations. + * + * @param {{name: string, directory: string}[]} structureImplementations + * @returns {Record} Namespace roots. + */ +function implementationNamespaceRoots(structureImplementations) { + const namespaceRoots = {}; + + for (const implementation of structureImplementations) { + if (!implementation.name || namespaceRoots[implementation.name]) continue; + namespaceRoots[implementation.name] = implementation.directory; + } + + if (!namespaceRoots.components && structureImplementations[0]?.directory) { + namespaceRoots.components = structureImplementations[0].directory; + } + + return namespaceRoots; +} + +/** + * Build Twig namespace roots for legacy/non-variant projects. + * + * @param {{projectDir: string, srcDir: string, srcExists: boolean, componentRootRecords: {name: string, directory: string}[]}} env + * @returns {Record} Namespace roots. + */ +function fallbackNamespaceRoots({ + projectDir, + srcDir, + srcExists, + componentRootRecords, +}) { + const namespaceRoots = {}; + const componentRoot = componentRootRecords[0]?.directory; + + if (componentRoot && safeExists(componentRoot)) { + namespaceRoots.components = componentRoot; + } + + const layoutRoot = unique( + [ + ...(srcExists ? [resolve(srcDir, 'layout')] : []), + resolve(projectDir, 'src/layout'), + resolve(projectDir, 'layout'), + ].filter(Boolean), + ).find(safeExists); + const tokensRoot = unique( + [ + ...(srcExists ? [resolve(srcDir, 'tokens')] : []), + resolve(projectDir, 'src/tokens'), + resolve(projectDir, 'tokens'), + ].filter(Boolean), + ).find(safeExists); + + if (layoutRoot) { + namespaceRoots.layout = layoutRoot; + } + if (tokensRoot) { + namespaceRoots.tokens = tokensRoot; + } + + return namespaceRoots; +} + +/** + * Resolve the serializable project structure model. + * + * @param {{ + * projectDir: string, + * srcDir: string, + * srcExists: boolean, + * SDC?: boolean, + * structureImplementations?: {name: string, directory: string}[], + * platformAdapter?: object + * }} env - Normalized project environment. + * @returns {object} Project structure model. + */ +export function resolveProjectStructure(env) { + const { + projectDir, + srcDir, + srcExists, + SDC = false, + platformAdapter = {}, + } = env; + const structureImplementations = + Array.isArray(env.structureImplementations) && + env.structureImplementations.length + ? env.structureImplementations + : Array.isArray(env.structureRoots) && env.structureOverrides + ? env.structureRoots.map((directory, index) => ({ + name: index === 0 ? 'components' : `structure-${index + 1}`, + directory, + })) + : []; + const structureOverrides = structureImplementations.length > 0; + const componentRootRecords = structureOverrides + ? structureImplementations + : fallbackComponentRoots({ projectDir, srcDir, srcExists }); + const globalRootRecords = structureOverrides + ? [] + : fallbackGlobalRoots({ srcDir, srcExists }); + const namespaceRoots = structureOverrides + ? implementationNamespaceRoots(structureImplementations) + : fallbackNamespaceRoots({ + projectDir, + srcDir, + srcExists, + componentRootRecords, + }); + const componentRoots = componentRootRecords.map((root) => root.directory); + const globalRoots = globalRootRecords.map((root) => root.directory); + const namespaceRootValues = Object.values(namespaceRoots); + const sourceRoots = unique( + [...componentRoots, ...globalRoots].filter(Boolean), + ); + const sourceRootRecords = [...componentRootRecords, ...globalRootRecords]; + const componentStoryRoots = srcExists + ? componentRoots.filter((root) => !isSameOrInsideRoot(root, srcDir)) + : componentRoots; + const storyRoots = structureOverrides + ? componentRoots + : unique( + [...(srcExists ? [srcDir] : []), ...componentStoryRoots].filter( + Boolean, + ), + ); + const twigRoots = unique( + [ + ...componentRoots, + ...namespaceRootValues, + ...(structureOverrides ? [] : [srcDir]), + ].filter(Boolean), + ); + const mirrorComponentOutput = Boolean( + srcExists && + !structureOverrides && + platformAdapter?.build?.mirrorDistComponentsToRoot, + ); + + return { + structureOverrides, + componentRootRecords, + globalRootRecords, + componentRoots, + globalRoots, + sourceRoots, + sourceRootRecords, + storyRoots, + twigRoots, + namespaceRoots, + output: { + components: 'components', + global: 'global', + js: 'js', + css: 'css', + storybook: 'storybook', + }, + outputStrategy: platformAdapter?.outputStrategy || 'dist', + outputMode: platformAdapter?.outputStrategy || 'dist', + mirrorComponentOutput, + SDC: Boolean(SDC), + }; +} + +/** + * Resolve the legacy relative key used by variant structure entries. + * + * Existing structure override builds strip the path below the first + * `components/` segment when one exists, otherwise they keep the project + * relative path. Preserve that behavior for entry-key compatibility. + * + * @param {string} filePath - Absolute source file path. + * @param {object} structure - Project structure model. + * @param {string} projectDir - Absolute project root. + * @returns {string} Project-relative key segment. + */ +function legacyStructureRelative(filePath, structure, projectDir) { + const relFromProject = relativeFrom(filePath, projectDir); + const componentRoot = findSourceRoot( + filePath, + structure.componentRootRecords, + ); + if (componentRoot?.name === 'components') { + return relativeFrom(filePath, componentRoot.directory); + } + return relFromProject; +} + +/** + * Resolve an output key for compiled JS or CSS. + * + * @param {string} filePath - Absolute source file path. + * @param {'js'|'css'} type - Asset type. + * @param {object} structure - Project structure model. + * @param {{projectDir: string, srcDir: string, SDC?: boolean}} ctx - Build context. + * @returns {string|null} Output key without extension. + */ +export function compiledAssetOutputPath(filePath, type, structure, ctx) { + const bucket = type === 'css' ? 'css' : 'js'; + const outputBase = + bucket === 'css' ? structure.output.css : structure.output.js; + + if (structure.structureOverrides) { + const rel = legacyStructureRelative(filePath, structure, ctx.projectDir); + return `${outputBase}/${stripAssetExtension(rel)}`; + } + + const componentRoot = findSourceRoot( + filePath, + structure.componentRootRecords, + ); + if (componentRoot) { + const rel = relativeFrom(filePath, componentRoot.directory); + return `${structure.output.components}/${injectBucket( + `${structure.output.components}/${rel}`, + bucket, + ctx.SDC, + ).replace(/^components\//, '')}`; + } + + const globalRoot = findSourceRoot(filePath, structure.globalRootRecords); + if (globalRoot) { + const rel = relativeFrom(filePath, globalRoot.directory); + return `${structure.output.global}/${injectBucket(rel, bucket, ctx.SDC)}`; + } + + return null; +} + +/** + * Resolve an output key for Storybook/component-library SCSS. + * + * @param {string} filePath - Absolute source file path. + * @param {object} structure - Project structure model. + * @param {{projectDir: string, srcDir: string}} ctx - Build context. + * @returns {string} Output key without extension. + */ +export function storybookStyleOutputPath(filePath, structure, ctx) { + const sourceRoot = findSourceRoot(filePath, structure.sourceRootRecords); + const relFromSrc = relativeFrom(filePath, ctx.srcDir); + const rel = + structure.structureOverrides || relFromSrc.startsWith('../') + ? structure.structureOverrides + ? relativeFrom(filePath, ctx.projectDir) + : relativeFrom(filePath, sourceRoot?.directory || ctx.srcDir) + : relFromSrc; + + return `${structure.output.storybook}/${rel.replace(/\.scss$/i, '')}`; +} + +/** + * Resolve copied component file destination relative to Vite outDir. + * + * @param {string} filePath - Absolute source file path. + * @param {object} structure - Project structure model. + * @returns {string|null} OutDir-relative destination. + */ +export function copiedComponentOutputPath(filePath, structure) { + const componentRoot = findSourceRoot( + filePath, + structure.componentRootRecords, + ); + if (!componentRoot) return null; + + const rel = relativeFrom(filePath, componentRoot.directory); + const base = structure.structureOverrides + ? componentRoot.name + : structure.output.components; + return `${base}/${rel}`; +} + +/** + * Resolve copied global file destination relative to Vite outDir. + * + * @param {string} filePath - Absolute source file path. + * @param {object} structure - Project structure model. + * @returns {string|null} OutDir-relative destination. + */ +export function copiedGlobalOutputPath(filePath, structure) { + const globalRoot = findSourceRoot(filePath, structure.globalRootRecords); + if (!globalRoot) return null; + + const rel = relativeFrom(filePath, globalRoot.directory); + if ( + rel === 'components' || + rel.startsWith('components/') || + rel === 'util' || + rel.startsWith('util/') + ) { + return null; + } + + return `${structure.output.global}/${rel}`; +} diff --git a/config/vite/test-utils/plugins.js b/config/vite/test-utils/plugins.js new file mode 100644 index 0000000..d3e52c5 --- /dev/null +++ b/config/vite/test-utils/plugins.js @@ -0,0 +1,66 @@ +/** + * @file Shared test helpers for Vite plugin unit tests. + */ + +import { mkdtempSync, writeFileSync } from 'fs'; +import { tmpdir } from 'os'; +import { join } from 'path'; +import Twig from 'twig'; + +import { registerTwigExtensions } from '../../../src/extensions/twig/index.js'; + +export const makeTempProject = () => + mkdtempSync(join(tmpdir(), 'emulsify-core-')); + +export const makeEnv = (projectDir, overrides = {}) => { + const srcDir = join(projectDir, 'src'); + + // Tests override only the environment values relevant to each scenario. + return { + projectDir, + srcDir, + srcExists: true, + platform: 'generic', + structureOverrides: false, + structureRoots: [], + ...overrides, + }; +}; + +export const pluginNames = (plugins) => + plugins.flat(Number.POSITIVE_INFINITY).map((plugin) => plugin?.name); + +export const transformTwigModule = (plugin, filePath) => + plugin.transform.call({ addWatchFile: jest.fn() }, '', filePath); + +export const twigInclude = (templatePath) => + `{% include ${JSON.stringify(templatePath)} %}`; + +export const twigEmbed = (templatePath) => + `{% embed ${JSON.stringify(templatePath)} %}`; + +export const renderGeneratedTwigModule = (code, context = {}) => { + const executable = code + .replace(/^\s*import Twig from 'twig';\s*/m, '') + .replace( + /^\s*import \{ registerTwigExtensions \} from '@emulsify\/core\/extensions\/twig';\s*/m, + '', + ) + .replace( + /export default \(context = \{\}\) => \{/, + 'return (context = {}) => {', + ); + const render = new Function('Twig', 'registerTwigExtensions', executable)( + Twig, + registerTwigExtensions, + ); + + return render(context); +}; + +export const writeProjectConfig = (projectDir, config) => { + writeFileSync( + join(projectDir, 'project.emulsify.json'), + JSON.stringify(config, null, 2), + ); +}; diff --git a/config/vite/test-utils/virtual-twig-globs.js b/config/vite/test-utils/virtual-twig-globs.js new file mode 100644 index 0000000..80a5dd9 --- /dev/null +++ b/config/vite/test-utils/virtual-twig-globs.js @@ -0,0 +1,6 @@ +/** + * @file Jest stub for the Vite-only Twig glob virtual module. + */ + +export const modules = {}; +export const sources = {}; diff --git a/config/vite/utils/fs-safe.js b/config/vite/utils/fs-safe.js new file mode 100644 index 0000000..3f60488 --- /dev/null +++ b/config/vite/utils/fs-safe.js @@ -0,0 +1,66 @@ +/** + * @file Safe filesystem helpers for Vite config and scripts. + */ + +import { existsSync, readFileSync } from 'fs'; + +/** + * Determine whether a path exists without throwing on inaccessible files. + * + * @param {string} filePath - Absolute or relative filesystem path. + * @returns {boolean} TRUE when the path exists. + */ +export function safeExists(filePath) { + try { + return existsSync(filePath); + } catch { + return false; + } +} + +/** + * Read a file without throwing when it is missing or inaccessible. + * + * @param {string} filePath - Absolute or relative filesystem path. + * @param {BufferEncoding} [encoding='utf8'] - File encoding. + * @returns {string} File contents, or an empty string when unavailable. + */ +export function safeReadFile(filePath, encoding = 'utf8') { + try { + return readFileSync(filePath, encoding); + } catch { + return ''; + } +} + +/** + * Read and parse a JSON file without throwing on missing files. + * + * Missing or empty files return an empty object. Invalid JSON returns the parse + * error so callers that report diagnostics can preserve that behavior. + * + * @param {string} filePath - Absolute or relative JSON file path. + * @returns {{data?: *, error?: Error}} Parsed result or parse error. + */ +export function safeReadJson(filePath) { + const source = safeReadFile(filePath); + if (!source) { + return {}; + } + + try { + return { data: JSON.parse(source) }; + } catch (error) { + return { error }; + } +} + +/** + * Return the first existing path from a candidate list. + * + * @param {string[]} candidates - Candidate filesystem paths. + * @returns {string|undefined} First existing path, when found. + */ +export function firstExistingPath(candidates = []) { + return candidates.filter(Boolean).find((candidate) => safeExists(candidate)); +} diff --git a/config/vite/utils/fs-safe.test.js b/config/vite/utils/fs-safe.test.js new file mode 100644 index 0000000..9392f38 --- /dev/null +++ b/config/vite/utils/fs-safe.test.js @@ -0,0 +1,65 @@ +/** + * @file Tests for safe filesystem utilities. + */ + +import { mkdtempSync, rmSync, writeFileSync } from 'fs'; +import { join } from 'path'; +import { tmpdir } from 'os'; +import { + firstExistingPath, + safeExists, + safeReadFile, + safeReadJson, +} from './fs-safe.js'; + +const makeTempDir = () => mkdtempSync(join(tmpdir(), 'emulsify-core-fs-')); + +describe('safe filesystem utilities', () => { + let tempDir; + + beforeEach(() => { + tempDir = makeTempDir(); + }); + + afterEach(() => { + rmSync(tempDir, { recursive: true, force: true }); + }); + + it('reads existing files and returns an empty string for missing files', () => { + const filePath = join(tempDir, 'example.txt'); + writeFileSync(filePath, 'content'); + + expect(safeReadFile(filePath)).toBe('content'); + expect(safeReadFile(join(tempDir, 'missing.txt'))).toBe(''); + }); + + it('reads valid JSON and preserves parse errors for callers', () => { + const validPath = join(tempDir, 'valid.json'); + const invalidPath = join(tempDir, 'invalid.json'); + writeFileSync(validPath, JSON.stringify({ name: 'Emulsify' })); + writeFileSync(invalidPath, '{'); + + expect(safeReadJson(validPath)).toEqual({ + data: { name: 'Emulsify' }, + }); + expect(safeReadJson(join(tempDir, 'missing.json'))).toEqual({}); + expect(safeReadJson(invalidPath).error).toBeInstanceOf(Error); + }); + + it('checks existence without throwing', () => { + const filePath = join(tempDir, 'exists.txt'); + writeFileSync(filePath, 'content'); + + expect(safeExists(filePath)).toBe(true); + expect(safeExists(join(tempDir, 'missing.txt'))).toBe(false); + }); + + it('returns the first existing candidate path', () => { + const first = join(tempDir, 'first.txt'); + const second = join(tempDir, 'second.txt'); + writeFileSync(second, 'content'); + + expect(firstExistingPath([null, first, second])).toBe(second); + expect(firstExistingPath([first])).toBeUndefined(); + }); +}); diff --git a/config/vite/utils/paths.js b/config/vite/utils/paths.js new file mode 100644 index 0000000..5ad55b7 --- /dev/null +++ b/config/vite/utils/paths.js @@ -0,0 +1,40 @@ +/** + * @file Shared filesystem path helpers for Vite config and scripts. + */ + +import { sep } from 'path'; + +/** + * Normalize a filesystem path to POSIX separators. + * + * Splitting on the host separator preserves existing path behavior on Windows, + * while the backslash replacement also normalizes Windows-style paths handled + * on non-Windows hosts. + * + * @param {string} filePath - Filesystem path. + * @returns {string} Path using forward slashes. + */ +export function toPosix(filePath) { + return filePath.split(sep).join('/').replace(/\\/g, '/'); +} + +/** + * Normalize a filesystem path to POSIX separators. + * + * @param {string} filePath - Filesystem path. + * @returns {string} Path using forward slashes. + */ +export const toPosixPath = toPosix; + +/** + * Replace the final slash in a POSIX path with a custom segment. + * + * @param {string} filePath - POSIX-style path. + * @param {string} replacement - Replacement string for the final slash. + * @returns {string} Path with the final slash replaced, or the original path. + */ +export function replaceLastSlash(filePath, replacement) { + const index = filePath.lastIndexOf('/'); + if (index === -1) return filePath; + return filePath.slice(0, index) + replacement + filePath.slice(index + 1); +} diff --git a/config/vite/utils/paths.test.js b/config/vite/utils/paths.test.js new file mode 100644 index 0000000..4f070c7 --- /dev/null +++ b/config/vite/utils/paths.test.js @@ -0,0 +1,31 @@ +/** + * @file Tests for shared path utilities. + */ + +import { sep } from 'path'; +import { replaceLastSlash, toPosix, toPosixPath } from './paths.js'; + +describe('Vite path utilities', () => { + it('normalizes host separators to POSIX separators', () => { + expect(toPosix(['src', 'components', 'button'].join(sep))).toBe( + 'src/components/button', + ); + }); + + it('normalizes Windows separators on any host', () => { + expect(toPosix('src\\components\\button')).toBe('src/components/button'); + expect(toPosixPath('C:\\theme\\src\\components')).toBe( + 'C:/theme/src/components', + ); + }); + + it('replaces the final slash with a bucket segment', () => { + expect(replaceLastSlash('components/card/card', '/css/')).toBe( + 'components/card/css/card', + ); + }); + + it('leaves slashless paths unchanged when replacing the final slash', () => { + expect(replaceLastSlash('card', '/css/')).toBe('card'); + }); +}); diff --git a/config/vite/utils/react-singleton.js b/config/vite/utils/react-singleton.js new file mode 100644 index 0000000..5349c18 --- /dev/null +++ b/config/vite/utils/react-singleton.js @@ -0,0 +1,85 @@ +/** + * @file React singleton helpers for Storybook and Vite config. + */ + +import { unique } from './unique.js'; + +/** + * React modules that must resolve from the consumer project root. + * + * @type {string[]} + */ +export const reactSingletonModules = [ + 'react', + 'react-dom', + 'react/jsx-runtime', + 'react/jsx-dev-runtime', +]; + +const asArray = (value) => (Array.isArray(value) ? value : []); + +const isObjectAlias = (alias) => + alias && typeof alias === 'object' && !Array.isArray(alias); + +/** + * Merge Vite alias config when all aliases use object syntax. + * + * Array-style aliases are already order-sensitive Vite config, so this helper + * leaves mixed/array alias forms to Vite's normal merge behavior. + * + * @param {...import('vite').UserConfig} configs - Vite config objects. + * @returns {object|undefined} Merged alias object when applicable. + */ +function mergeObjectAliases(...configs) { + const aliases = configs + .map((config) => config?.resolve?.alias) + .filter(Boolean); + + if (!aliases.length || aliases.some((alias) => !isObjectAlias(alias))) { + return undefined; + } + + return Object.assign({}, ...aliases); +} + +/** + * Merge Vite resolve config while forcing React to a single project instance. + * + * Later configs override earlier shallow resolve properties, while all dedupe + * lists are preserved and extended with React's runtime modules. + * + * @param {...import('vite').UserConfig} configs - Vite config objects. + * @returns {import('vite').UserConfig['resolve']} Merged resolve config. + */ +export function mergeReactSingletonResolve(...configs) { + const alias = mergeObjectAliases(...configs); + const mergedResolve = configs.reduce( + (merged, config) => ({ + ...merged, + ...(config?.resolve || {}), + }), + {}, + ); + + return { + ...mergedResolve, + ...(alias ? { alias } : {}), + dedupe: unique([ + ...configs.flatMap((config) => asArray(config?.resolve?.dedupe)), + ...reactSingletonModules, + ]), + }; +} + +/** + * Merge optimizeDeps include lists and include React singleton modules. + * + * @param {...string[]} includeLists - Existing optimizeDeps include arrays. + * @returns {string[]} Merged include list. + */ +export function mergeReactSingletonOptimizeDeps(...includeLists) { + return unique([ + ...includeLists.flatMap((includeList) => asArray(includeList)), + ...reactSingletonModules, + ]); +} diff --git a/config/vite/utils/react-singleton.test.js b/config/vite/utils/react-singleton.test.js new file mode 100644 index 0000000..8280767 --- /dev/null +++ b/config/vite/utils/react-singleton.test.js @@ -0,0 +1,49 @@ +/** + * @file Tests for React singleton Vite utilities. + */ + +import { + mergeReactSingletonOptimizeDeps, + mergeReactSingletonResolve, + reactSingletonModules, +} from './react-singleton.js'; + +describe('React singleton Vite utilities', () => { + it('adds React runtime modules to resolve.dedupe without dropping existing entries', () => { + expect( + mergeReactSingletonResolve( + { + resolve: { + alias: { '@core': '/core' }, + dedupe: ['twig', 'react'], + }, + }, + { + resolve: { + alias: { '@project': '/project' }, + dedupe: ['storybook'], + }, + }, + ), + ).toEqual({ + alias: { '@core': '/core', '@project': '/project' }, + dedupe: ['twig', 'react', 'storybook', ...reactSingletonModules.slice(1)], + }); + }); + + it('adds React runtime modules to optimizeDeps include without duplicates', () => { + expect( + mergeReactSingletonOptimizeDeps( + ['twig', 'react'], + ['@emulsify/core/extensions/twig', 'react-dom'], + ), + ).toEqual([ + 'twig', + 'react', + '@emulsify/core/extensions/twig', + 'react-dom', + 'react/jsx-runtime', + 'react/jsx-dev-runtime', + ]); + }); +}); diff --git a/config/vite/utils/unique.js b/config/vite/utils/unique.js new file mode 100644 index 0000000..f09b1d6 --- /dev/null +++ b/config/vite/utils/unique.js @@ -0,0 +1,36 @@ +/** + * @file Shared array de-duplication helpers. + */ + +/** + * Return values in first-seen order with duplicates removed. + * + * @template T + * @param {T[]} values - Values to deduplicate. + * @returns {T[]} Unique values. + */ +export function unique(values = []) { + return Array.from(new Set(values)); +} + +/** + * Return values in first-seen order with duplicates removed by key. + * + * @template T + * @param {T[]} values - Values to deduplicate. + * @param {(value: T) => *} keyFn - Function that returns a comparable key. + * @returns {T[]} Unique values. + */ +export function uniqueBy(values = [], keyFn) { + const seen = new Set(); + const result = []; + + for (const value of values) { + const key = keyFn(value); + if (seen.has(key)) continue; + seen.add(key); + result.push(value); + } + + return result; +} diff --git a/config/vite/utils/unique.test.js b/config/vite/utils/unique.test.js new file mode 100644 index 0000000..2d5c487 --- /dev/null +++ b/config/vite/utils/unique.test.js @@ -0,0 +1,30 @@ +/** + * @file Tests for shared uniqueness utilities. + */ + +import { unique, uniqueBy } from './unique.js'; + +describe('unique utilities', () => { + it('returns first-seen unique values without dropping falsey values', () => { + expect(unique(['a', 'b', 'a', '', '', 0, 0, false, false])).toEqual([ + 'a', + 'b', + '', + 0, + false, + ]); + }); + + it('deduplicates values by a computed key', () => { + const values = [ + { name: 'card', path: 'src/components/card' }, + { name: 'button', path: 'src/components/button' }, + { name: 'card', path: 'components/card' }, + ]; + + expect(uniqueBy(values, (value) => value.name)).toEqual([ + values[0], + values[1], + ]); + }); +}); diff --git a/config/vite/vite.config.js b/config/vite/vite.config.js new file mode 100644 index 0000000..39c4fdf --- /dev/null +++ b/config/vite/vite.config.js @@ -0,0 +1,157 @@ +/** + * @file Vite configuration for Emulsify. + * @see https://vite.dev/config/ + * + * @overview + * This configuration wires Emulsify's Vite build in a few clear steps: + * + * 1. Resolve the build environment (paths, platform flags) via {@link resolveEnvironment}. + * 2. Build the Rollup/Vite entries map with {@link buildInputs}. + * 3. Load optional project extensions (extra plugins and/or a config patcher) + * from `config/emulsify-core/vite/plugins.*` via {@link loadProjectExtensions}. + * 4. Assemble a base Vite config and optionally let the project extend/override + * parts of it by returning a patch object from `extendConfig(...)`. + * + * Notes: + * - CSS & JS sourcemaps are enabled. + * - CSS assets keep their path and drop the internal `__style` suffix if present. + */ + +import { defineConfig, mergeConfig } from 'vite'; +import path from 'node:path'; + +import { resolveEnvironment } from './environment.js'; +import { makePlugins } from './plugins.js'; +import { buildInputs } from './entries.js'; +import { loadProjectExtensions } from './project-extensions.js'; +import { mergeReactSingletonResolve } from './utils/react-singleton.js'; + +export default defineConfig(async () => { + /** + * Environment details for this build (project paths, platform, flags). + * @typedef {Object} EmulsifyEnv + * @property {string} projectDir - Absolute project root. + * @property {string} srcDir - Absolute source directory (`src/` if present, otherwise `components/`). + * @property {boolean} srcExists - Whether `src/` exists in the project. + * @property {string} platform - Deployment platform (e.g., `"drupal"`). + * @property {boolean} [SDC] - Single Directory Components toggle, if available. + * @property {boolean} [structureOverrides] - Whether component structure overrides are enabled. + * @property {string[]} [structureRoots] - Override roots, if provided. + * @property {object} [platformAdapter] - Active platform behavior adapter. + */ + + /** @type {EmulsifyEnv} */ + const env = resolveEnvironment(); + + // Build the Rollup/Vite entry map: keys encode output paths, values source files. + /** @type {Record} */ + const entries = buildInputs({ + projectDir: env.projectDir, + srcDir: env.srcDir, + srcExists: env.srcExists, + isDrupal: env.platform === 'drupal', + SDC: env.SDC, + structureOverrides: env.structureOverrides, + structureRoots: env.structureRoots, + structureImplementations: env.structureImplementations, + projectStructure: env.projectStructure, + }); + + // Load optional project-provided plugins and config patches. + /** + * @type {{ + * projectPlugins: import('vite').PluginOption[], + * extendConfig?: (base: import('vite').UserConfig, ctx: { env: EmulsifyEnv }) => import('vite').UserConfig + * }} + */ + const { projectPlugins, extendConfig } = await loadProjectExtensions({ env }); + + // Assemble the base config before applying project extensions. + /** @type {import('vite').UserConfig} */ + const base = { + // Treat the current working directory as the root. + root: process.cwd(), + + // Core plugin set + project-provided plugins (if any). + plugins: [...makePlugins(env), ...projectPlugins], + + // Keep React-based story helpers on the consumer project's React singleton. + resolve: mergeReactSingletonResolve(), + + // Generate CSS sourcemaps in dev; JS sourcemaps are set in `build.sourcemap`. + css: { + devSourcemap: true, + }, + + build: { + // Clean the output directory before building. + emptyOutDir: true, + + // All outputs are written into ./dist/ + outDir: 'dist/', + + // Emit production sourcemaps as well. + sourcemap: true, + + rollupOptions: { + // Multi-entry input map constructed above. + input: entries, + + // Keep file names deterministic and strip the internal CSS key suffix. + output: { + entryFileNames: '[name].js', + + /** + * Decide asset filenames. Normalizes `.css` paths and removes the `__style` + * suffix used to avoid name collisions in entry keys. + * @param {import('rollup').PreRenderedAsset} assetInfo + * @returns {string} + */ + assetFileNames: (assetInfo) => { + const file = assetInfo.name || assetInfo.fileName || ''; + if (file.endsWith('.css')) { + // Drop the CSS key suffix used to avoid JS/CSS entry collisions. + return file.replace(/__style(?=\.css$)/, ''); + } + const [original] = Array.isArray(assetInfo.originalFileNames) + ? assetInfo.originalFileNames + : assetInfo.originalFileName + ? [assetInfo.originalFileName] + : []; + if (original) { + const normalizedOriginal = path.normalize(original); + const relativeToProject = path.isAbsolute(normalizedOriginal) + ? path.relative(env.projectDir, normalizedOriginal) + : normalizedOriginal.replace(/^[/\\]+/, ''); + const normalizedRelative = relativeToProject + .split(path.sep) + .join('/'); + // Prevent traversing above dist/ if a relative path climbs directories. + const safePath = normalizedRelative.startsWith('..') + ? normalizedRelative.replace(/^(\.\.\/)+/g, '') + : normalizedRelative; + if (safePath) { + return safePath; + } + } + return 'assets/[name][extname]'; + }, + }, + }, + }, + + // Dev server tweaks; disable polling by default for performance. + server: { + watch: { usePolling: false }, + }, + }; + + // Let project extensions patch the final Vite config. + /** @type {import('vite').UserConfig} */ + const patched = + typeof extendConfig === 'function' + ? mergeConfig(base, extendConfig(base, { env }) || {}) + : base; + + return patched; +}); diff --git a/config/webpack/app.js b/config/webpack/app.js deleted file mode 100644 index 824fcb3..0000000 --- a/config/webpack/app.js +++ /dev/null @@ -1 +0,0 @@ -// Empty (needed for webpack) diff --git a/config/webpack/loaders.js b/config/webpack/loaders.js deleted file mode 100644 index 856042a..0000000 --- a/config/webpack/loaders.js +++ /dev/null @@ -1,167 +0,0 @@ -/** - * @fileoverview Webpack loader configurations for Emulsify Core and per-project overrides. - * - * This module exports a single default object containing loader definitions for: - * - JavaScript (with Babel) - * - Sass/CSS (with PostCSS + Autoprefixer or project overrides) - * - Images - * - SVG sprites - * - Twig templates - * - * It will look for these override files in your project: - * - ./config/emulsify-core/webpack/babel.config.cjs - * - ./config/emulsify-core/webpack/postcss.config.cjs - * - * If not found, it falls back to the package defaults. - */ - -import { createRequire } from 'module'; -import MiniCssExtractPlugin from 'mini-css-extract-plugin'; -import globImporter from 'node-sass-glob-importer'; -import fs from 'fs-extra'; -import path from 'path'; - -const require = createRequire(import.meta.url); - -/** @type {string} Path to the active Babel config file. */ -const babelConfig = fs.existsSync( - './config/emulsify-core/webpack/babel.config.cjs', -) - ? './config/emulsify-core/webpack/babel.config.cjs' - : require.resolve('@emulsify/core/config/babel.config.js'); - -/** @type {string} Path to the active PostCSS config file. */ -const postcssConfigPath = fs.existsSync( - './config/emulsify-core/webpack/postcss.config.cjs', -) - ? path.resolve('config/emulsify-core/webpack/postcss.config.cjs') - : require.resolve('@emulsify/core/config/postcss.config.js'); - -/** - * Resolve the directory of this file (without fileURLToPath). - * @type {string} - */ -let _filename = decodeURIComponent(new URL(import.meta.url).pathname); -if (process.platform === 'win32' && _filename.startsWith('/')) { - _filename = _filename.slice(1); -} -const _dirname = path.dirname(_filename); - -/** - * Root of the project (three levels up from this file). - * @type {string} - */ -const projectDir = path.resolve(_dirname, '../../../../..'); - -/** Absolute path to the folder that contains sprite source icons. */ -const ICONS_DIR = path.resolve(projectDir, 'assets/icons'); - -/** - * @type {import('webpack').RuleSetRule} - * JavaScript loader: transpile with Babel. - */ -const JSLoader = { - test: /^(?!.*\.(stories|component)\.js$).*\.js$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - configFile: babelConfig, - }, - }, -}; - -/** - * @type {import('webpack').RuleSetRule} - * CSS/Sass loader chain: - * - extract to file - * - css-loader (no URL rewriting) - * - postcss-loader (project or default) - * - sass-loader (with glob importer + compressed output) - */ -const CSSLoader = { - test: /\.s[ac]ss$/i, - exclude: /node_modules/, - use: [ - MiniCssExtractPlugin.loader, - { - loader: 'css-loader', - options: { - sourceMap: true, - url: false, - }, - }, - { - loader: 'postcss-loader', - options: { - sourceMap: true, - postcssOptions: { - config: postcssConfigPath, - }, - }, - }, - { - loader: 'sass-loader', - options: { - api: 'legacy', - sourceMap: true, - implementation: require('sass'), - webpackImporter: true, - sassOptions: { - importer: globImporter(), - legacyImporter: true, - outputStyle: 'compressed', - silenceDeprecations: ['legacy-js-api'], - quietDeps: true, - }, - }, - }, - ], -}; - -/** - * @type {import('webpack').RuleSetRule} - * Image loader: inlines small assets, emits larger ones. - */ -const ImageLoader = { - test: /\.(png|jpe?g|gif)$/i, - type: 'asset', -}; - -/** - * @type {import('webpack').RuleSetRule} - * General SVG loader for non-sprite SVGs (logos, illustrations, etc.). - * IMPORTANT: Excludes `assets/icons/` so `svg-spritemap-webpack-plugin` - * can consume those files without being intercepted by this rule. - */ -const SVGLoader = { - test: /icons\/.*\.svg$/, - type: 'asset/resource', - generator: { - filename: 'icons.svg', - }, - exclude: [ICONS_DIR], -}; - -/** - * @type {import('webpack').RuleSetRule} - * Twig.js loader for .twig templates. - */ -const TwigLoader = { - test: /\.twig$/, - use: { - loader: 'twigjs-loader', - }, -}; - -/** - * Default export of all loader configurations. - * @type {{ JSLoader: import('webpack').RuleSetRule, CSSLoader: import('webpack').RuleSetRule, ImageLoader: import('webpack').RuleSetRule, SVGSpriteLoader: import('webpack').RuleSetRule, TwigLoader: import('webpack').RuleSetRule }} - */ -export default { - JSLoader, - CSSLoader, - ImageLoader, - SVGLoader, - TwigLoader, -}; diff --git a/config/webpack/optimizers.js b/config/webpack/optimizers.js deleted file mode 100644 index f620516..0000000 --- a/config/webpack/optimizers.js +++ /dev/null @@ -1,26 +0,0 @@ -import ImageMinimizerPlugin from 'image-minimizer-webpack-plugin'; -import TerserPlugin from 'terser-webpack-plugin'; - -const ImageMinimizer = new ImageMinimizerPlugin({ - minimizer: { - implementation: ImageMinimizerPlugin.imageminMinify, - options: { - plugins: [ - ['jpegtran', { progressive: true }], - ['optipng', { optimizationLevel: 5 }], - ], - }, - }, -}); - -const TerserMinimizer = new TerserPlugin({ - terserOptions: { - mangle: { - reserved: ['Drupal', 'drupalSettings', 'once'], - }, - }, -}); - -export default { - minimizer: [ImageMinimizer, TerserMinimizer], -}; diff --git a/config/webpack/plugins.js b/config/webpack/plugins.js deleted file mode 100644 index 794c61f..0000000 --- a/config/webpack/plugins.js +++ /dev/null @@ -1,283 +0,0 @@ -import { resolve, dirname, relative } from 'path'; -import webpack from 'webpack'; -import { CleanWebpackPlugin } from 'clean-webpack-plugin'; -import RemoveEmptyScriptsPlugin from 'webpack-remove-empty-scripts'; -import MiniCssExtractPlugin from 'mini-css-extract-plugin'; -import SVGSpritemapPlugin from 'svg-spritemap-webpack-plugin'; -import CopyPlugin from 'copy-webpack-plugin'; -import { sync as globSync } from 'glob'; -import fs from 'fs-extra'; -import emulsifyConfig from '../../../../../project.emulsify.json' with { type: 'json' }; - -/** - * Resolve the directory of this file (without fileURLToPath). - * @type {string} - */ -let _filename = decodeURIComponent(new URL(import.meta.url).pathname); -if (process.platform === 'win32' && _filename.startsWith('/')) { - _filename = _filename.slice(1); -} -const _dirname = dirname(_filename); - -/** - * Project root (five levels up). - * @type {string} - */ -const projectDir = resolve(_dirname, '../../../../..'); - -/** - * Where source files live. - * Prefer `/src`; fall back to `/components` (legacy layout). - * @type {string} - */ -const srcPath = resolve(projectDir, 'src'); -const isSrcExists = fs.pathExistsSync(srcPath); -const srcDir = isSrcExists ? srcPath : resolve(projectDir, 'components'); - -/** - * Where built assets live. - * If `src/` exists, use `/dist`; else write into `/components`. - * @type {string} - */ -const distPath = isSrcExists - ? resolve(projectDir, 'dist') - : resolve(projectDir, 'components'); - -/** - * Platform switch (affects component output roots). - * @type {boolean} - */ -const isDrupal = emulsifyConfig?.project?.platform === 'drupal'; - -/** - * Component source root: - * - with src/: `/src/components` - * - without src/: `/components` - * @type {string} - */ -const componentsSrcRoot = isSrcExists ? resolve(srcDir, 'components') : srcDir; - -/** - * Component output root (where compiled component assets go): - * - Drupal + src/: `components/…` - * - Otherwise: `dist/components/…` - * (Relative to `projectDir`; used by CopyPlugins `to:` path.) - * @type {string} - */ -const componentsOutRoot = - isDrupal && isSrcExists ? 'components' : 'dist/components'; - -/** - * Glob pattern for Twig & component meta files. These are copied as-is so - * Drupal/WordPress themes can consume them alongside compiled assets. - * @type {string} - */ -const componentFilesPattern = resolve( - srcDir, - '**/*.{twig,component.yml,component.json}', -); - -/** - * Build CopyPlugin patterns from a glob matcher, preserving source structure. - * - * @param {string} filesMatcher - Glob for files to mirror. - * @returns {Array<{from:string,to:string}>} Copy patterns for CopyPlugin. - */ -function getPatterns(filesMatcher) { - return globSync(filesMatcher).map((file) => { - const projectPath = file.split('/src/')[0]; // base path before /src/ - const srcStructure = file.split(`${srcDir}/`)[1]; - const parentDir = srcStructure.split('/')[0]; - - // Consolidate foundation/layout under "components" for Drupal. - const consolidateDirs = - parentDir === 'layout' || parentDir === 'foundation' - ? '/components/' - : '/'; - - const filePath = file.split(/(foundation\/|components\/|layout\/)/)[2]; - - const to = isDrupal - ? `${projectPath}${consolidateDirs}${parentDir}/${filePath}` - : `${projectPath}/dist/${parentDir}/${filePath}`; - - return { from: file, to }; - }); -} - -/** - * CopyPlugin instance (only when `src/` exists): - * copies Twig and component meta files 1:1 into their expected destinations. - * @type {CopyPlugin|false} - */ -const CopyTwigPlugin = isSrcExists - ? new CopyPlugin({ patterns: getPatterns(componentFilesPattern) }) - : false; - -/* -------------------------------------------------------------------------- */ -/* COMPONENT & GLOBAL ASSETS */ -/* -------------------------------------------------------------------------- */ - -/** - * Asset allow-list (extensions we consider "static assets" to mirror). - * Extend to suit your project (e.g., add `pdf`, `txt`, `xml`, etc.). - * NOTE: We purposefully exclude code-like files via the filter below. - * @type {RegExp} - */ -const ASSET_EXT_RE = - /\.(?:png|jpe?g|gif|svg|webp|avif|ico|bmp|heic|heif|mp4|webm|mp3|ogg|wav|aac|woff2?|ttf|otf|eot|json|webmanifest|manifest|pdf)$/i; - -/** - * Exclude code & tooling files (don’t mirror these). - * @type {RegExp} - */ -const EXCLUDE_CODE_RE = - /\.(?:jsx?|tsx?|mjs|cjs|vue|svelte|scss|sass|less|styl|css|map|twig|php|yml|yaml|md|markdown|story(?:book)?\.[jt]sx?|stories\.[jt]sx?|test\.[jt]sx?)$/i; - -/** - * Shared filter for CopyPlugin patterns. - * Decides whether a file should be copied as a "static asset". - * - * @param {string} resourcePath - Absolute file path on disk. - * @param {string} base - The context directory for the pattern. - * @returns {boolean} True if we should copy the file. - */ -const assetFilter = (resourcePath, base) => { - const rel = relative(base, resourcePath); - // Guard: stay inside context - if (rel.startsWith('..')) return false; - // Exclude typical code/tooling files - if (EXCLUDE_CODE_RE.test(rel)) return false; - // Include known asset extensions - return ASSET_EXT_RE.test(rel); -}; - -/** - * Copy **all static assets inside components**, regardless of folder labels. - * - * Examples (all preserved under the component’s output root): - * src/components/accordion/assets/dropdown-icon.svg - * src/components/accordion/images/icons/chevron.svg - * src/components/accordion/icon.svg (root-level asset) - * - * @type {CopyPlugin} - */ -const CopyComponentAssetsPlugin = new CopyPlugin({ - patterns: [ - { - // Start at the components root and evaluate every file - from: '**/*', - context: componentsSrcRoot, - to: resolve(projectDir, componentsOutRoot, '[path][name][ext]'), - noErrorOnMissing: true, - globOptions: { - dot: false, - ignore: [ - '**/.DS_Store', - '**/Thumbs.db', - '**/node_modules/**', - '**/dist/**', - ], - }, - // Only copy files that match our asset allow-list and are not code - filter: (resourcePath) => assetFilter(resourcePath, componentsSrcRoot), - }, - ], -}); - -/** - * OPTIONAL: Copy **global (non-component) assets** that live under `src/` - * but outside `src/components/` (e.g. layout/site assets). - * - * Mirrors them under `dist/global/…`. - * Disabled when there is no `src/` directory. - * - * @type {CopyPlugin|false} - */ -const CopyGlobalAssetsPlugin = isSrcExists - ? new CopyPlugin({ - patterns: [ - { - from: '!(components|util)/**/*', - context: srcDir, - to: resolve(projectDir, 'dist', 'global', '[path][name][ext]'), - noErrorOnMissing: true, - globOptions: { - dot: false, - ignore: [ - '**/.DS_Store', - '**/Thumbs.db', - '**/node_modules/**', - '**/dist/**', - ], - }, - filter: (resourcePath) => assetFilter(resourcePath, srcDir), - }, - ], - }) - : false; - -/* -------------------------------------------------------------------------- */ -/* OTHER PLUGINS */ -/* -------------------------------------------------------------------------- */ - -/** - * CleanWebpackPlugin configuration. - * Wipes out compiled CSS/JS in `distPath` before a build; keeps images. - */ -const CleanPlugin = new CleanWebpackPlugin({ - protectWebpackAssets: false, - cleanOnceBeforeBuildPatterns: [ - `${distPath}/**/*.css`, - `${distPath}/**/*.js`, - `!${distPath}/**/*.png`, - `!${distPath}/**/*.jpg`, - `!${distPath}/**/*.gif`, - `!${distPath}/**/*.svg`, - ], -}); - -/** Removes empty JS files generated for style-only entries. */ -const RemoveEmptyJS = new RemoveEmptyScriptsPlugin(); - -/** - * MiniCssExtractPlugin: emit CSS next to the entry key path (no hard-coded dist/). - */ -const CssExtractPlugin = new MiniCssExtractPlugin({ - filename: ({ chunk }) => `${chunk.name}.css`, - chunkFilename: ({ chunk }) => `${chunk.name}.css`, -}); - -/** - * Generate a single SVG spritemap at `dist/icons.svg`. - */ -const SpritePlugin = new SVGSpritemapPlugin( - resolve(projectDir, 'assets/icons/**/*.svg'), - { - output: { - filename: 'dist/icons.svg', - chunk: { keep: true }, - }, - sprite: { - prefix: '', - generate: { title: false }, - }, - }, -); - -/** Build progress output. */ -const ProgressPlugin = new webpack.ProgressPlugin(); - -/** - * Export plugin instances keyed for easy inclusion in your Webpack config. - */ -export default { - ProgressPlugin, - CleanWebpackPlugin: CleanPlugin, - RemoveEmptyJS, - MiniCssExtractPlugin: CssExtractPlugin, - SpritePlugin, - CopyTwigPlugin, - CopyComponentAssetsPlugin, - CopyGlobalAssetsPlugin, -}; diff --git a/config/webpack/resolves.js b/config/webpack/resolves.js deleted file mode 100644 index 437d258..0000000 --- a/config/webpack/resolves.js +++ /dev/null @@ -1,157 +0,0 @@ -/** - * @fileoverview Configures Twig alias resolution for the project. - * - Builds Twig alias map from files under the source directory - * - Exposes a Webpack-style `resolve.alias` object for `.twig` files - */ - -import { - basename, - resolve, - relative, - isAbsolute, - join, - posix as path, -} from 'node:path'; -import { sync as globSync } from 'glob'; -import fs from 'fs-extra'; -import emulsifyConfig from '../../../../../project.emulsify.json' with { type: 'json' }; - -/** - * Resolve the directory of this file (without fileURLToPath). - * @type {string} - */ -let _filename = decodeURIComponent(new URL(import.meta.url).pathname); -if (process.platform === 'win32' && _filename.startsWith('/')) { - _filename = _filename.slice(1); -} -const _dirname = path.dirname(_filename); - -/** @type {string} Absolute project root (five levels up). */ -const projectDir = resolve(_dirname, '../../../../..'); - -/** @type {string} Project machine name used to prefix Drupal aliases. */ -const projectName = String(emulsifyConfig?.project?.name || '').trim(); - -/** - * Determine the source directory: prefer `/src` if it exists, - * otherwise use `/components`. If we choose `components` and it - * does not exist, create it safely inside the project. - * - * @returns {string} Absolute path to the source directory. - */ -function resolveOrCreateSrcDir() { - const srcPreferred = resolve(projectDir, 'src'); - if (fs.pathExistsSync(srcPreferred)) return srcPreferred; - - const componentsFallback = resolve(projectDir, 'components'); - if (!fs.pathExistsSync(componentsFallback)) { - ensureDirSafe(componentsFallback, { - base: projectDir, - allowedBasenames: new Set(['components']), - }); - } - return componentsFallback; -} - -/** - * Safely create a directory after validating it is a subpath of `base` - * and its basename is explicitly allowed. This addresses - * `security/detect-non-literal-fs-filename`. - * - * @param {string} dir - Absolute path to create. - * @param {{ base: string, allowedBasenames: Set }} opts - Safety options. - * @returns {void} - * @throws {Error} If the path is outside `base` or not allowed. - */ -function ensureDirSafe(dir, { base, allowedBasenames }) { - const rel = relative(base, dir); - const name = basename(dir); - - // Block absolute or escaping paths (outside of base) - if (!rel || rel.startsWith('..') || isAbsolute(rel)) { - throw new Error(`Refusing to create directory outside project: "${dir}"`); - } - - // Only allow known, expected directory names - if (!allowedBasenames.has(name)) { - throw new Error(`Refusing to create unexpected directory: "${name}"`); - } - - // The argument is validated; create the directory. - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.mkdirSync(dir, { recursive: true }); -} - -/** @type {string} Absolute source directory. */ -const srcDir = resolveOrCreateSrcDir(); - -/** @type {string} Glob pattern for all non-partial Twig files (skip leading underscores). */ -const aliasPattern = resolve(srcDir, '**/!(_*).twig'); - -/** - * Read immediate subdirectories from a source directory. - * - * @param {string} source - Absolute directory to scan. - * @returns {string[]} Array of directory names (basenames only). - */ -function getDirectories(source) { - /* eslint-disable security/detect-non-literal-fs-filename */ - const entries = fs.readdirSync(source, { withFileTypes: true }); - /* eslint-enable security/detect-non-literal-fs-filename */ - return entries.filter((d) => d.isDirectory()).map((d) => d.name); -} - -/** - * Strip a leading two-digit ordering prefix from a directory name - * (e.g., "01-components" -> "components"). - * - * @param {string} dir - Original directory name. - * @returns {string} Cleaned directory name. - */ -function cleanDirectoryName(dir) { - return /^\d{2}-/.test(dir) ? dir.slice(3) : dir; -} - -/** - * Build a Twig alias object by: - * - Adding per-file aliases for Drupal (e.g., "mytheme/button") - * - Adding top-level section aliases (e.g., "@components", "@layout") - * - * @param {string} twigGlob - Glob pattern to locate Twig files. - * @returns {Record} Alias map ({ alias: absolutePath }). - */ -function getAliases(twigGlob) { - /** @type {Record} */ - const aliases = {}; - - // Per-file aliases for Drupal only: "/" - if (emulsifyConfig?.project?.platform === 'drupal' && projectName) { - for (const file of globSync(twigGlob)) { - const relToSrc = relative(srcDir, file); - const fileName = basename(relToSrc).replace(/\.twig$/, ''); - aliases[`${projectName}/${fileName}`] = file; - } - } - - // Top-level "@section" aliases for easier imports - const topDirs = getDirectories(srcDir); - for (const dir of topDirs) { - const name = cleanDirectoryName(dir); - aliases[`@${name}`] = join(projectDir, basename(srcDir), dir); - } - - return aliases; -} - -/** - * Webpack-style `resolve` config for Twig files. - * @typedef {{ extensions: string[], alias: Record }} TwigResolveConfig - */ - -/** @type {TwigResolveConfig} */ -const TwigResolve = { - extensions: ['.twig'], - alias: getAliases(aliasPattern), -}; - -export default { TwigResolve }; diff --git a/config/webpack/sdc-loader.js b/config/webpack/sdc-loader.js deleted file mode 100644 index 2d568c6..0000000 --- a/config/webpack/sdc-loader.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * A loader function that replaces occurrences of "projectName:" with "projectName/". - * - * @param {string} source - The source string to process. - * @returns {string} The transformed source. - */ -export default function (source) { - const projectName = this.getOptions().projectName || ''; - /* eslint-disable security/detect-non-literal-regexp */ - const result = source.replace( - new RegExp(`${projectName}:`, 'g'), - `${projectName}/`, - ); - /* eslint-enable security/detect-non-literal-regexp */ - return result; -} diff --git a/config/webpack/webpack.common.js b/config/webpack/webpack.common.js deleted file mode 100644 index 1146e94..0000000 --- a/config/webpack/webpack.common.js +++ /dev/null @@ -1,272 +0,0 @@ -/** - * @fileoverview Build Webpack entries and export the configuration. - * - Discovers JS/SCSS assets (base + component) via glob patterns - * - Shapes output paths based on platform and SDC (singleDirectoryComponents) - * - Wires up loaders, plugins, and optimizations - */ - -import { posix as path } from 'node:path'; -import { sync as globSync } from 'glob'; -import fs from 'fs-extra'; - -import loaders from './loaders.js'; -import plugins from './plugins.js'; -import resolves from './resolves.js'; -import optimizers from './optimizers.js'; -import emulsifyConfig from '../../../../../project.emulsify.json' with { type: 'json' }; - -/** - * Resolve the directory of this file (without fileURLToPath). - * @type {string} - */ -let _filename = decodeURIComponent(new URL(import.meta.url).pathname); -if (process.platform === 'win32' && _filename.startsWith('/')) { - _filename = _filename.slice(1); -} -const _dirname = path.dirname(_filename); - -/** @type {string} Absolute project root (five levels up from this file). */ -const projectDir = path.resolve(_dirname, '../../../../..'); - -/** @type {boolean} True when a "src/" directory exists (WP layout). */ -const hasSrc = fs.pathExistsSync(path.resolve(projectDir, 'src')); - -/** @type {string} The canonical source directory ("src" if present, else "components"). */ -const srcDir = hasSrc - ? path.resolve(projectDir, 'src') - : path.resolve(projectDir, 'components'); - -/** @type {boolean} True when platform is Drupal (affects component output root). */ -const isDrupal = emulsifyConfig?.project?.platform === 'drupal'; - -/** @type {boolean} Respect SDC (single-directory-components) layout if explicitly true. */ -const SDC = Boolean(emulsifyConfig?.project?.singleDirectoryComponents); - -/** @type {string} Output base for "global" assets. */ -const globalOutBase = hasSrc ? 'dist/global' : 'dist'; - -/** - * Create a path under the component output root. - * - In Drupal + src layout, components resolve to "components/…" - * - Otherwise, they resolve to "dist/components/…" - * @param {string} subpath - Component-local subpath (no extension). - * @returns {string} Component output path segment. - */ -const componentOutPath = (subpath) => - (isDrupal && hasSrc ? 'components' : 'dist/components') + '/' + subpath; - -/** - * Join segments with POSIX semantics (forward slashes), trimming empties. - * @param {...string} segs - Path segments. - * @returns {string} POSIX-joined path. - */ -const pj = (...segs) => path.join(...segs.filter(Boolean)); - -/** - * Compute the “dist subpath” for a non-component asset. - * Inserts a type folder ("js" or "css") when SDC = false. - * Drops the original file extension. - * @param {string} absFile - Absolute file path. - * @param {'js'|'css'} type - Asset type. - * @returns {string} Subpath under the global output base (no extension). - */ -const distSubpathForBase = (absFile, type) => { - const rel = path.relative(srcDir, absFile); - const dir = path.dirname(rel); - const ext = path.extname(rel); - const name = path.basename(rel, ext); - const outTypeDir = type === 'css' ? 'css' : 'js'; - return SDC ? pj(dir, name) : pj(dir, outTypeDir, name); -}; - -/** - * Compute the “dist subpath” for a component asset located under "…/components". - * Inserts a type folder ("js" or "css") when SDC = false. - * Drops the original file extension. - * @param {string} absFile - Absolute file path. - * @param {'js'|'scss'} type - Source type (scss maps to 'css'). - * @returns {string} Component-local subpath (no extension). - */ -const distSubpathForComponent = (absFile, type) => { - const relFromComponents = path.relative(pj(srcDir, 'components'), absFile); - const dir = path.dirname(relFromComponents); - const isStyle = type === 'scss'; - const outTypeDir = isStyle ? 'css' : 'js'; - const ext = isStyle ? '.scss' : '.js'; - const name = path.basename(relFromComponents, ext); - return SDC ? pj(dir, name) : pj(dir, outTypeDir, name); -}; - -/** - * Sanitize a file path by removing unwanted characters. - * - * @param {string} inputPath - The file path to sanitize. - * @returns {string} The sanitized file path. - */ -const sanitizePath = (inputPath) => inputPath.replace(/[^a-zA-Z0-9/_-]/g, ''); - -/** - * Reject keys that could touch object internals even after sanitization. - * @param {string} k - * @returns {boolean} - */ -const isDangerousKey = (k) => - k.includes('__proto__') || k.includes('prototype') || k === 'constructor'; - -/** - * Add a file under an entry key; if the key exists, merge to an array. - * Keeps JS before SCSS for deterministic order. - * - * @param {Map} map - * @param {string} key - * @param {string} file - * @returns {void} - */ -const addEntry = (map, key, file) => { - const safeKey = sanitizePath(String(key)); - if (!safeKey || isDangerousKey(safeKey)) return; - - const current = map.get(safeKey); - - if (!current) { - map.set(safeKey, file); - return; - } - - const arr = Array.isArray(current) ? current : [current]; - if (!arr.includes(file)) arr.push(file); - - // Optional: ensure JS comes before SCSS - arr.sort((a, b) => { - const ax = a.endsWith('.js') ? 0 : 1; - const bx = b.endsWith('.js') ? 0 : 1; - return ax - bx || a.localeCompare(b); - }); - - map.set(safeKey, arr); -}; - -/** - * Safe glob wrapper: returns [] if the pattern is falsy. - * @param {string} pattern - Glob pattern. - * @returns {string[]} Matching file paths. - */ -const glob = (pattern) => (pattern ? globSync(pattern) : []); - -/* -------------------------------------------------------------------------- */ -/* GLOBS */ -/* -------------------------------------------------------------------------- */ - -const BaseScssPattern = hasSrc - ? pj(srcDir, '!(components|util)/**/!(_*|cl-*|sb-*).scss') - : ''; - -const ComponentScssPattern = hasSrc - ? pj(srcDir, 'components/**/!(_*|cl-*|sb-*).scss') - : pj(srcDir, '**/!(_*|cl-*|sb-*).scss'); - -const ComponentLibraryScssPattern = pj(srcDir, '**/*{cl-*,sb-*}.scss'); - -const BaseJsPattern = hasSrc - ? pj(srcDir, '!(components|util)/**/!(*.stories|*.component|*.min|*.test).js') - : ''; - -const ComponentJsPattern = hasSrc - ? pj(srcDir, 'components/**/!(*.stories|*.component|*.min|*.test).js') - : pj(srcDir, '**/!(*.stories|*.component|*.min|*.test).js'); - -/* -------------------------------------------------------------------------- */ -/* ENTRY BUILD */ -/* -------------------------------------------------------------------------- */ - -/** - * Build the complete Webpack entries map. - * @returns {Record} Webpack entries. - */ -const buildEntries = () => { - /** @type {Map} */ - const entries = new Map(); - - /* ----------------------------- Base / Global JS ----------------------------- */ - for (const file of glob(BaseJsPattern)) { - const sub = distSubpathForBase(file, 'js'); - // If no "src/", legacy layout puts global JS directly under "dist/js". - const outRoot = hasSrc ? pj(globalOutBase) : pj('dist', 'js'); - addEntry(entries, pj(outRoot, sub), file); - } - - /* --------------------------- Component JS (no dist) -------------------------- */ - for (const file of glob(ComponentJsPattern)) { - if (file.includes('/dist/')) continue; // guard against accidental recursion - const sub = distSubpathForComponent(file, 'js'); - addEntry(entries, componentOutPath(sub), file); - } - - /* ------------------------------ Base / Global CSS --------------------------- */ - for (const file of glob(BaseScssPattern)) { - const sub = distSubpathForBase(file, 'css'); - // If no "src/", legacy layout puts global CSS directly under "dist/css". - const outRoot = hasSrc ? pj(globalOutBase) : pj('dist', 'css'); - addEntry(entries, pj(outRoot, sub), file); - } - - /* ---------------------------- Component CSS (SCSS) --------------------------- */ - for (const file of glob(ComponentScssPattern)) { - const sub = distSubpathForComponent(file, 'scss'); // maps to css - addEntry(entries, componentOutPath(sub), file); - } - - /* -------------------------- Component Library (Storybook) -------------------- */ - for (const file of glob(ComponentLibraryScssPattern)) { - const rel = path.relative(srcDir, file).replace(/\.scss$/, ''); - addEntry(entries, pj('dist', 'storybook', rel), file); - } - - return Object.fromEntries(entries); -}; - -/* -------------------------------------------------------------------------- */ -/* WEBPACK CONFIG EXPORT */ -/* -------------------------------------------------------------------------- */ - -export default { - target: 'web', - stats: { errorDetails: true }, - externals: { - drupal: 'Drupal', - drupalSettings: 'drupalSettings', - }, - entry: buildEntries(), - module: { - rules: [ - loaders.CSSLoader, - loaders.SVGSpriteLoader, - loaders.ImageLoader, - loaders.JSLoader, - loaders.TwigLoader, - ], - }, - plugins: [ - plugins.RemoveEmptyJS, - plugins.MiniCssExtractPlugin, - plugins.ImageminPlugin, - plugins.SpritePlugin, - plugins.ProgressPlugin, - plugins.CopyTwigPlugin, - plugins.CopyComponentAssetsPlugin, - ...(plugins.CopyGlobalAssetsPlugin ? [plugins.CopyGlobalAssetsPlugin] : []), - plugins.CleanWebpackPlugin, - ], - output: { - path: projectDir, - filename: '[name].js', - }, - resolve: resolves.TwigResolve, - optimization: optimizers, - // Quiet deprecation noise from Sass @import warnings - ignoreWarnings: [ - (warning) => - Boolean(warning?.message) && - /Sass @import rules are deprecated/.test(warning.message), - ], -}; diff --git a/config/webpack/webpack.dev.js b/config/webpack/webpack.dev.js deleted file mode 100644 index 40f727d..0000000 --- a/config/webpack/webpack.dev.js +++ /dev/null @@ -1,41 +0,0 @@ -import fs from 'fs-extra'; -import { resolve, dirname } from 'path'; -import { merge } from 'webpack-merge'; -import common from './webpack.common.js'; - -// JSON import syntax may vary; adjust if you need `assert { type: 'json' }` instead -import emulsifyConfig from '../../../../../project.emulsify.json' with { type: 'json' }; - -// Create __filename from import.meta.url without fileURLToPath -let _filename = decodeURIComponent(new URL(import.meta.url).pathname); - -// On Windows, remove the leading slash (e.g. "/C:/path" -> "C:/path") -if (process.platform === 'win32' && _filename.startsWith('/')) { - _filename = _filename.slice(1); -} - -const _dirname = dirname(_filename); - -// Get directories for file contexts. -const projectDir = resolve(_dirname, '../../../../..'); - -const srcPath = resolve(projectDir, 'src'); -const srcExists = fs.pathExistsSync(srcPath); -const isDrupal = emulsifyConfig.project.platform === 'drupal'; - -// Always ignore dist -const ignored = ['**/dist/**']; - -// If it’s Drupal and there is no src/, also ignore components -if (isDrupal && !srcExists) { - ignored.push('**/components/**'); -} - -export default merge(common, { - mode: 'development', - devtool: 'source-map', - watch: true, - watchOptions: { - ignored, - }, -}); diff --git a/config/webpack/webpack.prod.js b/config/webpack/webpack.prod.js deleted file mode 100644 index 6fe59c0..0000000 --- a/config/webpack/webpack.prod.js +++ /dev/null @@ -1,6 +0,0 @@ -import { merge } from 'webpack-merge'; -import common from './webpack.common.js'; - -export default merge(common, { - mode: 'production', -}); diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..85cc7c5 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,15 @@ +# Emulsify Core Documentation + +These docs expand on the short project README and are organized by the task a project maintainer is usually trying to complete. + +| Topic | Use This When | +| ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| [Version Evolution](version-evolution.md) | Understanding how Emulsify Core has evolved across major releases. | +| [Component Authoring](component-authoring.md) | Choosing Twig, React, or mixed Storybook authoring and comparing component examples. | +| [Storybook](storybook.md) | Rendering Twig stories, using `renderTwig()`, understanding Twig runtime helpers, and mixing Twig with React stories. | +| [Project Structure And Output](project-structure.md) | Configuring `src/components`, root `./components`, `variant.structureImplementations`, and expected output paths. | +| [Platform Adapters](platform-adapters.md) | Understanding `generic`, `drupal`, platform resolution order, and Drupal SDC behavior. | +| [Extension Points](extension-points.md) | Adding Vite plugins, Tailwind CSS, Storybook preview overrides, and other framework tooling. | +| [Performance](performance.md) | Understanding sourcemaps, eager Twig imports, Tailwind scanning, copied files, and fixture validation. | +| [Native Twig Extensions](native-twig-extensions.md) | Using `bem()`, `add_attributes()`, and `switch/case/default/endswitch` in Twig.js. | +| [Migration](migration-4x.md) | Upgrading from earlier versions while preserving existing structures. | diff --git a/docs/component-authoring.md b/docs/component-authoring.md new file mode 100644 index 0000000..0d18da6 --- /dev/null +++ b/docs/component-authoring.md @@ -0,0 +1,235 @@ +# Component Authoring + +Emulsify Core supports component-driven development with Vite and Storybook. Twig-based components and React components are both complete, intentional authoring models. A project can be Twig-first, React-first, or intentionally mixed. + +## Choosing An Authoring Model + +Twig is a good fit for CMS themes and server-rendered template systems where production markup is rendered by Twig. Drupal has a dedicated adapter today. Craft CMS, WordPress + Timber, and other Twig-based CMS projects can use the generic adapter unless they need project-specific integration code. + +React is a good fit for standalone UI packages, application components, and design systems consumed by React applications. + +Mixed libraries use Twig and React in the same Storybook instance. This works well when a design system needs to document both CMS-rendered components and JavaScript-rendered application components. + +## Twig Component Libraries + +Twig imports are transformed into render functions that accept Storybook args as Twig context. Use `renderTwig()` from `@emulsify/core/storybook` to render imported Twig templates in React-based Storybook. + +```js +import template from './button.twig'; +import { renderTwig } from '@emulsify/core/storybook'; + +export default { + title: 'Components/Button', +}; + +export const Default = { + render: renderTwig(template), + args: { + text: 'Read more', + }, +}; +``` + +Storybook's Twig runtime supports Emulsify's native Twig helpers plus `include()` and `source()` through the normalized project structure model. Drupal-specific Twig filters are registered only when the active platform adapter enables Drupal behavior. + +## Component Metadata Imports + +Component metadata files such as `*.component.yml` can be imported from stories +and Vite-side modules. YAML imports provide a default export with the full +parsed metadata object. Top-level keys that are valid JavaScript export names +are also available as named exports: + +```js +import metadata, { props } from './accordion.component.yml'; +``` + +Keys that are not safe JavaScript export names, such as `$schema` or +`display-name`, are not emitted as named exports. They remain available from the +default metadata object. + +## React Component Libraries + +React components render through Storybook's React/Vite support. Storybook discovers React stories from the same normalized story roots as Twig stories. The shared Storybook globs include `*.stories.js`, `*.stories.jsx`, `*.stories.ts`, and `*.stories.tsx`; fixture coverage validates JavaScript/JSX stories. + +```jsx +import { Button } from './Button'; + +export default { + title: 'Components/Button', + component: Button, +}; + +export const Default = { + args: { + text: 'Read more', + }, +}; +``` + +## Mixed Twig And React Storybook Libraries + +Twig and React stories can share the same title hierarchy, Storybook addons, Sass conventions, and project structure. They do not need to share implementation details. + +```text +src/ + components/ + button/ + button.twig + button.stories.js + button.scss + badge/ + Badge.jsx + badge.stories.jsx + badge.scss +``` + +Both stories appear in the same Storybook instance. Twig stories should use `renderTwig()` for imported Twig templates when authored or actively migrated. Older Twig stories that return HTML strings directly remain compatible through the shared Storybook preview. React stories use standard Storybook React component or render-function patterns. + +## Twig Button Example + +`button.twig`: + +```twig +{# + * @file + * Button component. + * + * Available variables: + * - text: Button text. + * - url: Optional URL. When present, renders an anchor. + * - icon: Optional icon name. + * - modifiers: Optional BEM modifiers. + #} + +{% set button_attributes = { + class: bem('button', modifiers|default([])), +} %} + +{% if url %} + + {{ text }} + {% if icon %} + + {% endif %} + +{% else %} + +{% endif %} +``` + +`button.stories.js`: + +```js +import template from './button.twig'; +import { renderTwig } from '@emulsify/core/storybook'; + +export default { + title: 'Components/Button', + render: renderTwig(template), + args: { + text: 'Read more', + url: '#', + icon: '→', + modifiers: ['primary'], + }, +}; + +export const Default = {}; +``` + +## React Button Example + +`Button.jsx`: + +```jsx +import './button.scss'; + +export function Button({ + text = 'Read more', + url, + icon, + modifiers = [], + onClick, +}) { + const classes = [ + 'button', + ...modifiers.map((modifier) => `button--${modifier}`), + ].join(' '); + + const content = ( + <> + {text} + {icon ? ( + + ) : null} + + ); + + if (url) { + return ( + + {content} + + ); + } + + return ( + + ); +} +``` + +`button.stories.jsx`: + +```jsx +import { Button } from './Button'; + +export default { + title: 'Components/Button', + component: Button, + args: { + text: 'Read more', + url: '#', + icon: '→', + modifiers: ['primary'], + }, +}; + +export const Default = {}; +``` + +## Shared Sass/CSS + +Twig and React components can share class naming conventions and styles, but they do not have to share implementation details. + +```scss +.button { + display: inline-flex; + align-items: center; + gap: 0.5rem; + text-decoration: none; +} + +.button--primary { + font-weight: 700; +} + +.button__icon { + line-height: 1; +} +``` + +Sass files in supported component roots are included in the Vite build. Files beginning with `_` are treated as partials and are excluded from direct build entry generation. Storybook-specific styles using `cl-*` or `sb-*` naming are routed to Storybook output paths. diff --git a/docs/extension-points.md b/docs/extension-points.md new file mode 100644 index 0000000..f6b122b --- /dev/null +++ b/docs/extension-points.md @@ -0,0 +1,208 @@ +# Extension Points + +Emulsify Core provides shared Vite and Storybook conventions. Project-specific framework tooling should live in the consuming project and connect through documented extension points. + +## Directory Conventions + +Project-level extension locations live under `config/emulsify-core`: + +| Extension Type | Directory | Why | +| --------------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------- | +| Vite plugins/config patches | `config/emulsify-core/vite/plugins.(mjs\|js\|cjs)` | Build-time Vite extensions are loaded only by Node/Vite. | +| Storybook overrides | `config/emulsify-core/storybook/...` | Storybook preview/head overrides are project-facing assets that Storybook imports. | +| A11y config | `config/emulsify-core/a11y.config.js` | The a11y script keeps the existing project config path for compatibility. | + +Vite extensions should use `config/emulsify-core/vite/`. Storybook overrides should continue using `config/emulsify-core/storybook/`, and the a11y script continues to read `config/emulsify-core/a11y.config.js`. + +## Vite Plugins And Config Patches + +Projects can extend the shared Vite config with one of these files: + +- `config/emulsify-core/vite/plugins.mjs` +- `config/emulsify-core/vite/plugins.js` +- `config/emulsify-core/vite/plugins.cjs` + +Supported plugin shapes: + +```js +export default [myVitePlugin()]; +``` + +```js +export default ({ env }) => [myVitePlugin({ env })]; +``` + +Projects can also export `extendConfig()` when they need to patch Vite config beyond adding plugins: + +```js +export const extendConfig = (config, { env }) => ({ + define: { + __PROJECT_NAME__: JSON.stringify(env.machineName), + }, +}); +``` + +Use plugin arrays for normal framework integration. Use `extendConfig()` only when a plugin does not expose the needed config directly. + +## Tailwind CSS + +For Tailwind CSS v4, install Tailwind in the project: + +```sh +npm install tailwindcss @tailwindcss/vite +``` + +Add the Tailwind Vite plugin from the project extension file: + +```js +// config/emulsify-core/vite/plugins.mjs +import tailwindcss from '@tailwindcss/vite'; + +export default () => [tailwindcss()]; +``` + +Create a CSS file that imports Tailwind. This example places it under `src/global`, but the file can live anywhere that makes sense for the project: + +```css +/* src/global/tailwind.css */ +@import 'tailwindcss'; + +/* Choose the source roots your project uses. */ +@source "../components"; +@source "../../components"; +@source "../foundation"; +@source "../layout"; +@source "../tokens"; +``` + +The `@source` lines are optional when Tailwind's automatic detection already sees the right files, but they make multi-root Emulsify projects explicit. Use `../components` for `src/components`, `../../components` for root `./components`, and add one line for each `variant.structureImplementations` root that should be scanned. Keep `@source` paths focused on active component source directories so Tailwind does not scan generated output, archived templates, or dependency folders. + +For production builds, import the Tailwind CSS file from a discovered JavaScript entry: + +```js +// src/global/tailwind.js +import './tailwind.css'; +``` + +For Storybook development, import the same CSS file from the project preview override so Twig and React stories see the same utility classes: + +```js +// config/emulsify-core/storybook/preview.js +import '../../../src/global/tailwind.css'; + +export const parameters = {}; +``` + +Tailwind detects complete class names in Twig, React, and other templates. Avoid constructing utility class fragments dynamically, such as `text-${color}-600`; map variants to complete class strings instead. + +## Other Vite Frameworks + +Other Vite-based framework integrations follow the same pattern: + +1. Install the framework package in the consuming project. +2. Return its Vite plugin from `config/emulsify-core/vite/plugins.*`. +3. Import any required framework CSS or setup files from a discovered project entry or Storybook preview override. +4. Use `extendConfig()` only when the framework needs additional Vite config. + +Emulsify Core should not carry optional framework dependencies for every consuming project. Keep those dependencies local to the project that uses them. + +## Storybook Main Overrides And Addons + +Projects can provide `config/emulsify-core/storybook/main.js` to extend the shared Storybook main configuration. Use this for Storybook features that belong in Node-side config, such as addons, additional static directories, or final config shaping. + +Project addons are appended to the Emulsify Core defaults, so a project can add one addon without repeating `@storybook/addon-a11y`, `@storybook/addon-links`, or `@storybook/addon-themes`. + +```sh +npm install @storybook/addon-viewport +``` + +```js +// config/emulsify-core/storybook/main.js +export default { + addons: ['@storybook/addon-viewport'], +}; +``` + +Addon objects are also supported. If a project provides the same addon package name as a default addon, the project entry replaces the default entry so options can be customized without creating duplicates. + +```js +// config/emulsify-core/storybook/main.js +export default { + addons: [ + { + name: '@storybook/addon-a11y', + options: { + manual: true, + }, + }, + ], +}; +``` + +When a project intentionally wants to replace the full addon list, export `replaceAddons`. + +```js +// config/emulsify-core/storybook/main.js +export const replaceAddons = true; + +export default { + addons: ['@storybook/addon-viewport'], +}; +``` + +For advanced cases, export `extendConfig()`. It receives the already-merged Storybook config and the resolved Emulsify environment. + +```js +// config/emulsify-core/storybook/main.js +export function extendConfig(config, { env }) { + const staticDirs = [...(config.staticDirs || [])]; + if (env.platform === 'generic') { + staticDirs.push('public'); + } + + return { + ...config, + staticDirs, + }; +} +``` + +## Storybook Preview Overrides + +Projects can provide `config/emulsify-core/storybook/preview.js` to override or extend Storybook preview parameters. Missing override files are ignored. Default a11y parameters remain in place unless explicitly overridden. + +```js +export const parameters = { + layout: 'centered', + a11y: { + config: { + detailedReport: false, + }, + }, +}; +``` + +Preview overrides are loaded in the browser-bundled Storybook preview through Vite-safe imports. They should not rely on CommonJS `require()`. + +## Preview And Manager Head HTML + +Preview head and manager head HTML remain separate extension points through: + +- `config/emulsify-core/storybook/preview-head.html` +- `config/emulsify-core/storybook/manager-head.html` + +Use preview head for markup needed inside the story iframe, such as fonts, meta tags, or scripts that rendered components depend on. Use manager head for Storybook chrome only. + +## Public Imports + +Emulsify Core exposes stable public package paths: + +`defineReactExtension` is reserved for future React extension support. It currently returns the input unchanged. Adopting the import path is safe; the runtime is intentionally a no-op until the registry lands. + +```js +import { renderTwig } from '@emulsify/core/storybook'; +import { registerTwigExtensions } from '@emulsify/core/extensions/twig'; +import { defineReactExtension } from '@emulsify/core/extensions/react'; +``` + +Vite consumers can import the shared config from `@emulsify/core/vite` and public Vite plugin helpers from `@emulsify/core/vite/plugins`. diff --git a/docs/migration-4x.md b/docs/migration-4x.md new file mode 100644 index 0000000..bc12fc6 --- /dev/null +++ b/docs/migration-4x.md @@ -0,0 +1,188 @@ +# Migration To The Current Release + +Emulsify Core now runs on Vite and React/Vite Storybook while preserving existing component structures. This guide is for projects upgrading from earlier Webpack-based versions. + +## Requirements + +Use Node.js 24 or later. All maintained scripts run `scripts/check-node-version.js` before doing work. + +## Upgrade Summary + +| Area | What Changed | What Did Not Change | What May Require Changes | +| ----------------------- | ---------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | +| Build tool | Vite replaces the Webpack build. | Component JS, Sass/CSS, Twig, metadata, and static assets still build or copy into deterministic paths. | Webpack-specific customizations should move to `config/emulsify-core/vite/plugins.*`. | +| Storybook | Storybook uses `@storybook/react-vite`. | Twig stories and React stories can live in the same Storybook instance. Existing Twig stories that return HTML strings are wrapped for compatibility. | Imported Twig templates should render through `renderTwig()` from `@emulsify/core/storybook` when stories are actively migrated. | +| Runtime | Node.js 24 is the supported floor. | Project scripts still run through npm and the shared Emulsify Core config. | Local developer machines and CI images must use Node.js 24 or later. | +| Project configuration | `project.emulsify.json` is the source of truth for platform and structure configuration. | Existing `src/components`, root `./components`, and configured `variant.structureImplementations` remain. | Projects missing `project.emulsify.json` should add one before relying on platform-specific behavior. | +| Platform behavior | Platform adapters control platform-specific behavior. Implemented adapters are currently `generic` and `drupal`. | Drupal SDC mirroring remains supported for Drupal projects that opt into it. | Non-Drupal projects should use `generic` unless a dedicated adapter exists. | +| Extension configuration | Vite extension files live under `config/emulsify-core/vite/plugins.*`. | Storybook overrides still live under `config/emulsify-core/storybook/...`; a11y config still lives at `config/emulsify-core/a11y.config.js`. | Projects with old Webpack override files should replace them with Vite extensions. | + +## Known Limitations + +Review the [Known Limitations](../README.md#known-limitations) before upgrading. The key points are that only `generic` and `drupal` adapters are implemented today, large Twig libraries should account for eager Storybook Twig imports, production sourcemaps are enabled unless overridden, Webpack customizations need manual Vite migration, and Drupal SDC mirroring applies only when the Drupal adapter and SDC settings are enabled. + +## What Changed + +- Webpack has been replaced with Vite. +- Storybook uses `@storybook/react-vite`. +- Twig rendering remains supported through Emulsify's Twig integration. +- React components are supported directly through Storybook's React/Vite setup. +- Twig and React stories can coexist in the same Storybook instance. +- `project.emulsify.json` is the source of truth for platform and structure configuration. +- Platform-specific behavior is controlled by platform adapters instead of being assumed globally. + +## What Did Not Change + +- Existing component roots do not need to move just to upgrade. +- Root `./components` remains a valid source structure. +- Drupal SDC output mirroring remains supported when the Drupal adapter and `project.singleDirectoryComponents` enable it. +- Twig component authoring remains supported. +- Component metadata and static component assets are still copied beside component output. + +## What May Require Changes + +- Update CI and local development to Node.js 24 or later. +- Move custom Webpack configuration to Vite plugins or `extendConfig()`. +- Existing Twig stories that return HTML strings can continue working during the upgrade. Use `npx --no-install emulsify-audit` to find stories that should move to `renderTwig()` and other upgrade-readiness items. +- Review any project code that assumed Drupal behavior in Storybook. Drupal behavior now comes from the Drupal adapter. +- Review Storybook-only Twig file volume for very large libraries. See [Performance](performance.md) for the eager Twig import tradeoff. + +## Component Structure Compatibility + +Existing projects should not need to move components just to upgrade. + +Supported source structures include: + +- `src/components` +- root `./components` +- configured `variant.structureImplementations` + +Projects with `variant.structureImplementations` should keep that configuration in `project.emulsify.json`; those roots are treated as intentional and are respected before fallback discovery. + +## Storybook Migration + +Storybook runs on React/Vite. Twig stories still work, but imported Twig templates should be rendered with `renderTwig()` from `@emulsify/core/storybook`. + +```js +import template from './button.twig'; +import { renderTwig } from '@emulsify/core/storybook'; + +export default { + title: 'Components/Button', + render: renderTwig(template), +}; + +export const Default = { + args: { + text: 'Read more', + }, +}; +``` + +React stories can be added alongside existing Twig components without changing the Twig components. + +For older function stories that return `template(args)` directly, Emulsify Core wraps string results as HTML in the shared preview. That compatibility layer is intended to reduce upgrade churn; `renderTwig()` is still the clearer pattern for stories you are editing. + +Run the audit script to list likely legacy Twig stories and other upgrade-readiness items: + +```sh +npx --no-install emulsify-audit +``` + +The audit scans normalized Emulsify source roots and checks for unresolved Twig +`include()` or `source()` references, CSS asset URLs that are missing or left to +runtime resolution, Webpack-era patterns, direct imports of Emulsify Core +internals, Drupal assumptions in non-Drupal projects, missing configured +structure roots, large Twig Storybook roots, and Twig stories that should move +to `renderTwig()`. + +Use `--fail-on-found` if you want to make the audit enforce migration progress in CI. If you only want the Twig story migration report, run `npx --no-install emulsify-audit-twig-stories`. + +## Install Warning Controls + +npm applies `overrides` only from the root package being installed. Overrides +inside `@emulsify/core` help this repository, but they do not automatically +apply when Core is installed as a dependency in a generated Drupal theme. + +Generated or consuming themes should include these root-level overrides to pick +up compatible transitive dependency patches used by Core's tooling: + +```json +{ + "overrides": { + "glob": "^13.0.6", + "locutus": "^3.0.36", + "minimatch@3.0.x": "^3.1.5" + } +} +``` + +These overrides are intentionally narrow. They do not replace the older Twig +integration packages; they only pin compatible transitive packages that reduce +known install warnings and audit noise while the Twig integration remains on the +current feature set. + +## Twig Runtime + +Emulsify Core's Storybook Twig runtime supports: + +- Native `bem()` and `add_attributes()` helpers. +- Native `switch`, `case`, `default`, and `endswitch` tags. +- Storybook `include()` and `source()` helpers backed by the normalized project structure model. +- Optional platform Twig extensions supplied by platform adapters. + +Drupal-specific Twig filters are only loaded when the Drupal adapter enables them. + +## Vituum Twig Integration + +Emulsify treats `@vituum/vite-plugin-twig` as a pinned integration point. The internal `vituum-patch.js` adapter removes Vituum build hooks that conflict with Emulsify's output model and fails fast if a future Vituum release changes the expected plugin shape, so projects should pin to a known-good Vituum version or update the adapter instead of accepting a silent rendering break. + +## Drupal Behavior + +Drupal-specific Storybook behavior comes from the Drupal platform adapter. Generic and unknown platforms do not create or require a Drupal global by default. + +Drupal SDC mirroring remains supported for Drupal projects that enable `singleDirectoryComponents`. + +## Vite Customization + +Replace Webpack-specific customizations with Vite configuration or `config/emulsify-core/vite/plugins.*` extensions. + +```js +// config/emulsify-core/vite/plugins.mjs +export default ({ env }) => [ + myVitePlugin({ + projectName: env.machineName, + }), +]; +``` + +See [Extension Points](extension-points.md) for Vite plugins, Tailwind CSS, Storybook preview overrides, and framework integrations. + +## CSS Asset URLs + +Vite resolves `url(...)` values relative to the stylesheet it is compiling. +When a stylesheet points outside the normalized Emulsify source roots, Vite may +leave the URL unchanged and print a message such as: + +```text +../../../assets/fonts/Avenir-Regular.woff2 referenced in ../../../assets/fonts/Avenir-Regular.woff2 didn't resolve at build time, it will remain unchanged to be resolved at runtime +``` + +That can be intentional in Drupal projects when the URL points at a theme asset +that Drupal serves directly. Verify that the unchanged URL is valid from the +compiled CSS file in `dist/` or mirrored `components/` output. + +To make Vite resolve and rebase the asset at build time, keep the asset under a +normalized source root and reference it relative to the authored stylesheet. If +the asset must remain in a project-level `assets/` directory, use a stable +runtime URL or add a project Vite extension that copies/rewrites the asset path. + +## Upgrade Checklist + +1. Use Node.js 24 or later. +2. Keep existing component roots unless you are intentionally restructuring. +3. Add or verify `project.emulsify.json`. +4. Move Webpack-specific customization to Vite extension files. +5. Run `npx --no-install emulsify-audit` and update actively maintained Twig stories to use `renderTwig()`. +6. Keep Drupal SDC settings in `project.singleDirectoryComponents` when needed. +7. Add React stories directly where useful; no Twig refactor is required. diff --git a/docs/native-twig-extensions.md b/docs/native-twig-extensions.md new file mode 100644 index 0000000..f4c9b38 --- /dev/null +++ b/docs/native-twig-extensions.md @@ -0,0 +1,75 @@ +# Native Twig Extensions + +Emulsify Core includes native Twig.js implementations for the Emulsify `bem()` and `add_attributes()` helpers, plus `switch`, `case`, `default`, and `endswitch` logic tags compatible with Emulsify Tools 2.x templates. These are registered through one shared extension registry so Storybook, Vite Twig rendering, and imported Twig component modules use the same behavior. + +The extension source lives under `src/extensions/`: + +- `src/extensions/twig/` contains Twig functions, logic tags, and registration helpers. +- `src/extensions/shared/` contains reusable HTML attribute and list utilities. +- `src/extensions/react/` contains React extension registry helpers. + +Storybook-only Twig runtime helpers live under `src/storybook/twig/`; see [Storybook](storybook.md) for `include()` and `source()`. + +## `bem()` + +`bem()` remains backward-compatible with the existing positional API: + +```twig +

+``` + +It also supports object syntax: + +```twig +

+``` + +The helper normalizes class values and supports arrays for modifiers and extra classes. It can be used directly in an attribute position or composed into `add_attributes()`. + +## `add_attributes()` + +`add_attributes()` renders HTML attributes from an object and can compose with `bem()` output: + +```twig +{% set additional_attributes = { + class: bem('title', ['small'], 'card'), + disabled: true +} %} + +

+``` + +Boolean `true` attributes render without a value, Boolean `false` and nullish values are omitted, and class-like values are normalized for predictable output. + +## `switch`, `case`, `default`, And `endswitch` + +`switch` statements support PHP-style scalar matching and multiple values per `case` with `or`: + +```twig +{% switch variant %} + {% case 'primary' or 'secondary' %} + {{ label }} + {% default %} + {{ label }} +{% endswitch %} +``` + +The implementation is designed for Twig.js templates that need parity with Emulsify Tools 2.x switch templates. It validates that `case` and `default` are used inside `switch` and supports nested expressions in case values. + +## Registering Extensions + +Most projects do not need to call the registration APIs directly; Emulsify Core's Vite and Storybook integrations register them. Direct consumers can register Twig extensions explicitly: + +```js +import Twig from 'twig'; +import { registerTwigExtensions } from '@emulsify/core/extensions/twig'; + +registerTwigExtensions(Twig); +``` + +Registration is idempotent per Twig instance. diff --git a/docs/performance.md b/docs/performance.md new file mode 100644 index 0000000..a951b4d --- /dev/null +++ b/docs/performance.md @@ -0,0 +1,93 @@ +# Performance + +Emulsify Core favors predictable output and simple project configuration. The defaults are suitable for small and medium component libraries, and the release fixtures cover the main supported structures. Larger libraries should keep source roots intentional and use the fixture commands below to compare changes. + +## Production Sourcemaps + +Vite production builds currently emit JavaScript and CSS sourcemaps: + +```js +build: { + sourcemap: true, +} +``` + +CSS dev sourcemaps are also enabled. Sourcemaps are useful during the release and migration window because they make compiled output easier to debug. They do increase `dist/` size. Projects that need a different production sourcemap policy can patch Vite config from `config/emulsify-core/vite/plugins.*`: + +```js +// config/emulsify-core/vite/plugins.mjs +export const extendConfig = () => ({ + build: { + sourcemap: false, + }, +}); +``` + +## Storybook Twig Imports + +Storybook's Twig resolver eagerly imports compiled Twig modules and raw Twig source strings with `import.meta.glob(..., { eager: true })`. + +This supports: + +- `include()` for Twig templates. +- `source()` for raw Twig source. +- Namespaces derived from `project.emulsify.json`. + +The eager strategy is simple and reliable, but every `.twig` file under Storybook's resolved Twig roots is included in the preview build. Large projects with many generated, archived, or CMS-only Twig files can see larger Storybook output and slower builds. + +For large libraries: + +- Keep only active Storybook-rendered Twig files under Storybook source roots. +- Move generated or archived Twig files outside `src/components`, root `./components`, or explicit `variant.structureImplementations` roots when Storybook does not need them. +- Prefer explicit `variant.structureImplementations` roots when a repository has multiple source areas. +- Avoid storing large raw fixtures under Twig roots unless `source()` needs to read them. + +## Tailwind Scanning + +Tailwind CSS v4 can scan project sources automatically, but explicit `@source` lines make Emulsify structures easier to reason about: + +```css +@import 'tailwindcss'; + +@source "../components"; +@source "../../components"; +@source "../foundation"; +@source "../layout"; +@source "../tokens"; +``` + +Use only the roots your project actually uses. Do not point Tailwind at `dist/`, `.out/`, `node_modules/`, generated fixture output, or archived templates. + +## Copied Files Versus Compiled Files + +Emulsify Core compiles JavaScript and Sass/CSS entries. It copies Twig templates, component metadata, and static component assets. + +Copied files are intentionally not transformed by Vite. This keeps CMS-facing templates and metadata predictable and avoids unnecessary build work. The copy pass uses the normalized project structure model so copied files land beside the matching compiled output. + +## Validation Commands + +Use these commands to compare release-readiness behavior: + +```sh +npm run fixtures:release +``` + +Release fixtures live under `.github/fixtures/release/`. They are repository +development assets for CI and local validation, and are not included in the npm +package installed by consuming projects. + +Run one fixture when debugging a specific project shape: + +```sh +npm run fixtures:release -- --fixture generic-src-components +npm run fixtures:release -- --fixture mixed-storybook +npm run fixtures:release -- --fixture large-twig-storybook +``` + +List available fixtures: + +```sh +npm run fixtures:release:list +``` + +The `large-twig-storybook` fixture reports Storybook build time, output size, and generated Twig component count. Treat those numbers as trend data for local comparison rather than fixed pass/fail budgets. diff --git a/docs/platform-adapters.md b/docs/platform-adapters.md new file mode 100644 index 0000000..421fc73 --- /dev/null +++ b/docs/platform-adapters.md @@ -0,0 +1,79 @@ +# Platform Adapters + +Platform adapters keep CMS-specific or framework-specific behavior out of the global defaults. Generic projects should not inherit Drupal behavior, and Drupal projects should keep SDC support when they opt into it. + +The implemented adapters are currently: + +- `generic` +- `drupal` + +Emulsify Core supports Twig-based authoring for CMS-oriented projects, but WordPress + Timber and Craft CMS do not have dedicated adapters in this package yet. Those projects can use `generic` behavior today when they do not need platform-specific Storybook behavior or output mirroring. + +## Platform Resolution + +The active platform is resolved in this order: + +1. `EMULSIFY_PLATFORM` +2. `project.platform` +3. `variant.platform` +4. `generic` + +Unknown platform names currently use generic adapter behavior while preserving the resolved platform string. This lets future integrations add their own adapters without forcing Drupal behavior onto every project. + +## `generic` + +The generic adapter keeps output in `dist/`. It does not load Drupal behavior shims, does not call `Drupal.attachBehaviors()`, and does not register Drupal Twig filters by default. + +Use `generic` for standalone Twig libraries, React libraries, mixed Storybook libraries, Craft CMS projects, WordPress + Timber projects, or any non-Drupal project that does not need platform-specific output behavior. For CMS projects without a dedicated adapter, `generic` means Emulsify Core provides Twig Storybook/runtime support and normal `dist/` output, but it does not add CMS-specific filters, behavior hooks, or mirroring. + +```json +{ + "project": { + "platform": "generic", + "name": "example", + "machineName": "example" + } +} +``` + +## `drupal` + +The Drupal adapter owns Drupal-specific behavior: + +- Storybook loads the Drupal behavior shim. +- Storybook calls `Drupal.attachBehaviors()` after story render and args updates. +- Drupal Twig filters are registered by default. +- Drupal SDC component output can mirror from `dist/components` to root `./components`. + +```json +{ + "project": { + "platform": "drupal", + "name": "whisk", + "machineName": "whisk", + "singleDirectoryComponents": true + } +} +``` + +Drupal behavior attachment and Drupal SDC mirroring should not be assumed for generic, React-only, WordPress + Timber, Craft CMS, or other non-Drupal projects. + +## Drupal SDC Behavior + +Drupal SDC compatibility is controlled by `project.singleDirectoryComponents` and the Drupal platform adapter. + +When a Drupal project uses `src/components` and `singleDirectoryComponents` is `true`, component output is built through `dist/components` and mirrored back to root `./components` for Drupal SDC compatibility. The mirrored root files are the files Drupal consumes. + +Generic, React-only, and non-Drupal projects do not mirror component output to root `./components` by default. Root `./components` can still be a source directory for older projects; that is separate from Drupal SDC mirroring. + +## Future Platforms + +Future adapters should own their platform-specific behavior instead of changing global defaults. Good adapter responsibilities include: + +- Behavior attachment hooks. +- Optional Twig filters or functions. +- Output strategies. +- Static asset handling. +- CMS-specific mirroring or copy behavior. + +WordPress + Timber and Craft CMS can use generic Twig behavior today. Dedicated adapters can be added later when those integrations need platform-specific defaults such as CMS filters, behavior hooks, asset handling, or output conventions. diff --git a/docs/project-structure.md b/docs/project-structure.md new file mode 100644 index 0000000..130eef5 --- /dev/null +++ b/docs/project-structure.md @@ -0,0 +1,116 @@ +# Project Structure And Output + +Emulsify Core reads `project.emulsify.json` once and normalizes project structure for Vite, Storybook, Twig namespaces, and copy behavior. + +## Which Structure Should I Use? + +| Project Type | Recommended Structure | Platform Setting | Notes | +| -------------------------------------------- | -------------------------------------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------- | +| New generic design system | `src/components` | `generic` | Good default for Twig, React, or mixed component libraries that do not need CMS-specific output behavior. | +| Existing root `./components` project | Keep `./components` | `generic` or `drupal` | Valid for upgrades. Do not create `src/` only to satisfy Emulsify Core. | +| Drupal SDC theme | `src/components` with SDC enabled | `drupal` | Builds through `dist/components` and mirrors component output to root `./components` for Drupal consumption. | +| Multi-root design system | `variant.structureImplementations` | `generic` or `drupal` | Use explicit named roots such as `components`, `foundation`, `layout`, and `tokens`. | +| CMS Twig project without a dedicated adapter | `src/components` or explicit structure roots | `generic` | Use this for Craft CMS, WordPress + Timber, or similar Twig-based projects today. Dedicated adapters are not implemented yet. | + +## Supported Project Structures + +### `src/components` + +`src/components` is the recommended structure for new projects. + +```text +src/ + components/ + button/ + button.twig + button.stories.js + button.scss +``` + +When `src/` exists, global styles and scripts can live elsewhere under `src/`, outside `src/components` and `src/util`. + +### Root `./components` + +Root `./components` remains valid for existing projects. + +```text +components/ + button/ + button.twig + button.stories.js + button.scss +``` + +Projects using this structure do not need to create `src/` just to use the current build system. Generic builds emit into `dist/`; Drupal SDC mirroring happens only when the Drupal adapter enables it. + +### `variant.structureImplementations` + +`variant.structureImplementations` is explicit configuration in `project.emulsify.json`. When present, those directories are respected above fallback discovery. + +```json +{ + "project": { + "platform": "generic", + "name": "example", + "machineName": "example" + }, + "variant": { + "structureImplementations": [ + { "name": "components", "directory": "./src/components/" }, + { "name": "foundation", "directory": "./src/foundation/" }, + { "name": "layout", "directory": "./src/layout/" }, + { "name": "tokens", "directory": "./src/tokens/" } + ] + } +} +``` + +Each implementation name becomes a structure root and Twig namespace, so templates can reference names such as `@components`, `@foundation`, `@layout`, and `@tokens`. Configured paths that resolve outside the project root are ignored. + +## Story Roots + +Stories remain colocated with components. Storybook discovers stories from the normalized source roots regardless of whether a project uses: + +- `src/components` +- root `./components` +- one or more `variant.structureImplementations` directories + +Supported story extensions are `*.stories.js`, `*.stories.jsx`, `*.stories.ts`, and `*.stories.tsx`. Release fixture coverage validates JavaScript/JSX stories. + +## Twig Namespace Roots + +Twig namespaces are derived from the same normalized project structure. For explicit structure implementations, each configured name becomes a namespace. + +```twig +{{ include('@components/button/button.twig') }} +{{ include('@foundation/icon/icon.twig') }} +{{ include('@layout/grid/grid.twig') }} +{{ source('@tokens/colors/colors.twig') }} +``` + +For fallback structures, Emulsify Core exposes `@components` when a component root exists and may expose roots such as `@layout` or `@tokens` when those directories exist. + +## Output Path Matrix + +The Vite outDir is `dist/` unless a platform adapter performs additional work after build. The release fixture suite asserts the paths below. + +| Project type | JS output | CSS output | Twig output | Component metadata | Assets | Storybook styles | +| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | +| `src/components` generic project | `dist/components//js/.js`; global JS under `dist/global/**/js/*.js` | `dist/components//css/.css`; global CSS under `dist/global/**/css/*.css` | `dist/components//.twig` | `dist/components//*.component.yml` when present | `dist/components//` | `dist/storybook//.css` | +| `src/components` Drupal SDC project | Mirrored to `components//.js` | Mirrored to `components//.css` | Mirrored to `components//.twig` | Mirrored to `components//*.component.yml` | Mirrored to `components//` | `dist/storybook//.css` | +| Root `./components` project | `dist/components//js/.js` | `dist/components//css/.css` | `dist/components//.twig` | `dist/components//*.component.yml` when present | `dist/components//` | `dist/storybook//.css` | +| `variant.structureImplementations` project | Component-root JS can emit as `dist/js//.js`; non-`components` roots preserve project-relative paths such as `dist/js/src/foundation/colors/colors.js` | Component-root CSS can emit as `dist/css//.css`; non-`components` roots preserve project-relative paths such as `dist/css/src/foundation/colors/colors.css` | Copied under each named root, such as `dist/components/**`, `dist/layout/**`, or `dist/tokens/**` | Copied under the named root when present | Copied under the named root, such as `dist/components/button/button.asset.txt` or `dist/foundation/colors/palette.json` | `dist/storybook//.css` | +| React-only Storybook project | Storybook builds React stories directly; Vite entry output applies to discovered `.js` and `.scss` files in supported roots | Same Sass routing as the matching project structure | Not emitted unless Twig files exist | Not emitted unless component metadata exists | Copied when non-code assets exist in supported roots | Same Storybook style routing as the matching project | + +## Entry And Copy Rules + +Emulsify Core preserves current exclusion behavior for build inputs: + +- Partial Sass files are not direct build entries. +- Stories are not compiled as production component assets. +- Component metadata is copied, not compiled. +- Minified files are excluded from entry generation. +- Test files are excluded from entry generation. +- `cl-*` and `sb-*` Storybook styles are routed to Storybook output paths. + +Asset copying and entry generation both consume the normalized project structure model so roots, namespaces, and output paths stay aligned. diff --git a/docs/storybook.md b/docs/storybook.md new file mode 100644 index 0000000..f15d5dc --- /dev/null +++ b/docs/storybook.md @@ -0,0 +1,229 @@ +# Storybook + +Emulsify Core uses `@storybook/react-vite`. React components render directly through Storybook's React framework, and Twig templates render through Emulsify's Twig story helper. + +## Twig Stories + +Twig imports are transformed into render functions that return HTML strings. Use `renderTwig()` from `@emulsify/core/storybook` to adapt those functions to React-based Storybook stories. + +```js +import template from './card.twig'; +import { renderTwig } from '@emulsify/core/storybook'; + +export default { + title: 'Components/Card', + render: renderTwig(template), + args: { + heading: 'Example', + body: 'Twig rendered inside React Storybook.', + }, +}; + +export const Default = {}; +``` + +`renderTwig()` passes Storybook args as Twig context, re-renders when args change, and attaches platform behavior only when the active platform adapter enables it. + +## Legacy Twig Story Compatibility + +Older Emulsify stories often export functions that call an imported Twig template directly and return the rendered HTML string: + +```js +import template from './accordion.twig'; + +export const Accordion = (args) => + template({ + accordion__heading: args.heading, + }); +``` + +Those stories still render in Emulsify Core. The shared Storybook preview wraps plain string results as HTML so projects can upgrade without rewriting every component immediately. It also tolerates older decorators that stringify `story()` for Twig stories. React stories and stories that already return React elements pass through unchanged. + +`renderTwig()` remains the preferred pattern for new or actively migrated Twig stories because it makes the Twig/React Storybook boundary explicit: + +```js +import template from './accordion.twig'; +import { renderTwig } from '@emulsify/core/storybook'; + +const context = (args) => ({ + accordion__heading: args.heading, +}); + +export default { + title: 'Components/Accordion', + render: renderTwig(template, { context }), +}; + +export const Accordion = {}; +``` + +Generated projects can include legacy Twig story checks in the full project +readiness audit with: + +```sh +npm run audit +``` + +The full audit scans normalized Emulsify source roots and checks Twig +`include()` and `source()` references, CSS asset URLs, Webpack-era patterns, +platform assumptions, and public Emulsify Core import paths. + +Projects with `@emulsify/core` installed can call the package binary directly: + +```sh +npx --no-install emulsify-audit +``` + +From an Emulsify Core checkout, pass the project root explicitly: + +```sh +node scripts/audit.js --root /path/to/project +``` + +For only the Twig story migration report, use `npm run audit:twig-stories` from this repo or `npx --no-install emulsify-audit-twig-stories` from a consuming project. + +Add `--fail-on-found` when using the audit in CI during a migration push. + +## React Stories + +React stories use standard Storybook React patterns. + +```jsx +import { Card } from './Card'; + +export default { + title: 'Components/Card', + component: Card, + args: { + heading: 'Example', + body: 'React rendered in the same Storybook instance.', + }, +}; + +export const Default = {}; +``` + +Twig and React stories are discovered from the same normalized story roots. They can share title hierarchy, Sass conventions, global preview configuration, and addons. + +## Storybook Twig Runtime + +Twig support in Storybook is optional and platform-agnostic. When Twig stories are used, Emulsify Core configures Twig.js with: + +- Native Emulsify Twig helpers such as `bem()` and `add_attributes()`. +- Native Emulsify Twig logic tags such as `switch`, `case`, `default`, and `endswitch`. +- Storybook runtime support for `include()` and `source()`. +- Compiled template dependency support for `{% include %}`, `{% embed %}`, `{% extends %}`, `{% import %}`, and `{% from %}`. +- Optional platform Twig extensions supplied by the active adapter. + +Drupal-specific Twig filters are not part of the generic Twig runtime. They are registered only when the active platform adapter enables them. + +## Twig Import Performance + +Storybook's Twig resolver uses Vite `import.meta.glob()` calls generated from the normalized project structure model. It eagerly imports both compiled Twig template modules and raw Twig source strings: + +- Template modules support `{% include %}`, `{% embed %}`, `{% extends %}`, `{% import %}`, and `{% from %}` dependencies. +- Raw source imports support `source()`. + +The eager strategy is intentionally simple and stable for the current Storybook integration. It makes all configured Twig namespaces available at render time without asynchronous resolver plumbing, so Twig stories can render predictably beside React stories. For small and medium component libraries, this is acceptable and keeps the release behavior easy to reason about. + +The tradeoff is that every `.twig` file under the resolved Twig roots is included in the Storybook preview bundle, even when only a few stories directly render those templates. Large libraries with many templates, generated Twig files, or archived component variants can see slower Storybook builds and larger preview output. + +Large projects should keep Storybook-facing Twig roots intentional: + +- Keep active story templates under supported component or structure roots. +- Keep generated, archived, or CMS-only Twig files outside Storybook source roots when they do not need to render in Storybook. +- Use `variant.structureImplementations` to make source roots explicit when a project has multiple areas such as `components`, `foundation`, `layout`, and `tokens`. +- Avoid placing large raw text fixtures under Twig roots unless `source()` needs them. + +Release validation includes a larger Twig Storybook fixture. To collect repeatable local measurements, run: + +```sh +npm run fixtures:release +``` + +To run only that measurement fixture: + +```sh +npm run fixtures:release -- --fixture large-twig-storybook +``` + +The `large-twig-storybook` fixture prints Storybook build time, static output size, and the generated Twig component count. Those numbers are intended for trend comparison between branches and machines, not as fixed performance budgets. + +A lazy resolver/cache model is feasible later because the resolver already centralizes template and source lookup behind `createTwigResolver()`. That change should be handled separately from this release because it would alter how Twig modules are loaded, watched, and cached in Storybook. + +## `include()` + +`include()` resolves templates through the normalized project structure model. References can use configured Twig namespaces such as `@components`, `@foundation`, `@layout`, or `@tokens` when those roots exist in `project.emulsify.json`. + +```twig +{{ include('@components/icon/icon.twig', { + name: 'arrow-right' +}) }} +``` + +The runtime supports explicit variables, `with_context`, `ignore_missing`, and ordered template candidates: + +```twig +{{ include([ + '@components/card/card.twig', + '@components/fallback/fallback.twig' +], { + heading: 'Example', + with_context: true, + ignore_missing: true +}) }} +``` + +## `source()` + +`source()` can return raw Twig source from the same normalized template roots. + +```twig +
{{ source('@components/button/button.twig') }}
+``` + +It also supports the Storybook asset alias `@assets` for static assets served from the project asset directory. + +```twig +{{ source('@assets/icons/arrow.svg') }} +{{ source('@assets/images/example.png') }} +``` + +Text assets such as SVG, HTML, Twig, CSS, JavaScript, JSON, TXT, and Markdown are inlined when available. Raster image assets produce image markup. Other assets return a public URL. + +## Mixed Twig And React Folder Example + +```text +src/ + components/ + button/ + button.twig + button.stories.js + button.scss + badge/ + Badge.jsx + badge.stories.jsx + badge.scss +``` + +Both stories appear in the same Storybook instance and can be organized by the same title hierarchy. + +## Preview Overrides + +Projects can provide `config/emulsify-core/storybook/preview.js` to override or extend Storybook preview parameters. Missing override files are ignored. Default a11y parameters remain in place unless explicitly overridden. + +```js +export const parameters = { + layout: 'centered', + a11y: { + config: { + detailedReport: false, + }, + }, +}; +``` + +Preview head and manager head HTML remain separate extension points through: + +- `config/emulsify-core/storybook/preview-head.html` +- `config/emulsify-core/storybook/manager-head.html` diff --git a/docs/version-evolution.md b/docs/version-evolution.md new file mode 100644 index 0000000..f6f5bf5 --- /dev/null +++ b/docs/version-evolution.md @@ -0,0 +1,31 @@ +# Version Evolution + +Emulsify Core has always focused on one job: package the build, Storybook, linting, and component-library conventions that Emulsify projects need, while still giving individual projects room to extend those conventions. + +The current release keeps that goal and moves the implementation forward. It replaces the older Webpack-centered stack with Vite, uses React/Vite Storybook, supports Twig and React stories in the same library, and uses `project.emulsify.json` as the source of truth for platform and structure decisions. + +## 1.x: Shared Tooling Foundation + +The first major version established Emulsify Core as a reusable package instead of a set of copied project files. It bundled Storybook, Webpack, linting, a11y checks, Sass processing, Twig-related build support, asset handling, and project override hooks. + +That release made it practical for themes and standalone projects to consume shared Emulsify tooling from npm while still keeping project-specific configuration in the consuming project. + +## 2.x: Project Structure And Drupal SDC Support + +The second major version expanded how Emulsify Core handled project structure. It added better support for older component layouts, multi-level component directories, global and foundational asset processing, Storybook static directories, and Drupal-oriented SDC workflows. + +This version also continued dependency and Storybook upgrades while making more behavior configurable through project-level files. The important compatibility lesson from this era remains true: projects should not have to move working component directories just to keep using Emulsify Core. + +## 3.x: Runtime Modernization + +The third major version moved the package into a more modern JavaScript runtime model. It adopted ESM, raised the runtime floor to Node 24, kept dependencies current, refined PostCSS and Sass handling, improved component asset copying, and continued to preserve existing Drupal SDC behavior. + +It also set up the architectural runway for the current build model by cleaning up module scope, Storybook behavior, asset resolution, and package compatibility work. + +## Current Release: Vite, React/Vite Storybook, And Platform Adapters + +The current release is the next evolution of Emulsify Core. Vite replaces Webpack as the build engine. Storybook runs on the React/Vite framework. Twig templates render through Emulsify's Storybook helper, and React components render through normal Storybook React patterns. + +The project model is also more explicit. `project.emulsify.json` drives platform and structure configuration. The normalized structure model supports `src/components`, root `./components`, and custom `variant.structureImplementations`. Platform adapters own platform-specific behavior such as Drupal behavior attachment, Drupal Twig filters, and Drupal SDC output mirroring. + +That combination keeps existing Drupal and Twig-heavy projects viable while making Emulsify Core a better fit for generic Twig libraries, standalone React libraries, and mixed design systems. It is not a break from the project history; it is the same shared-tooling idea updated for the way modern component libraries are built. diff --git a/package-lock.json b/package-lock.json index 2ebd0f6..155f453 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,103 +1,92 @@ { "name": "@emulsify/core", - "version": "3.5.0", + "version": "4.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@emulsify/core", - "version": "3.5.0", + "version": "4.0.0", "license": "GPL-2.0", "dependencies": { - "@babel/core": "^7.28.5", - "@babel/preset-env": "^7.28.5", + "@babel/core": "^7.28.4", + "@babel/eslint-parser": "^7.28.6", + "@babel/preset-env": "^7.28.3", "@emulsify/cli": "^1.11.4", - "@eslint/js": "^10.0.1", - "@storybook/addon-a11y": "^9.1.20", - "@storybook/addon-links": "^9.1.20", - "@storybook/addon-styling-webpack": "^2.0.0", - "@storybook/addon-themes": "^9.1.20", - "@storybook/builder-webpack5": "^9.1.20", - "@storybook/server-webpack5": "^9.1.20", - "add-attributes-twig-extension": "^0.1.0", + "@eslint/js": "^9.39.4", + "@storybook/addon-a11y": "^10.1.4", + "@storybook/addon-links": "^10.1.4", + "@storybook/addon-themes": "^10.1.4", + "@storybook/react": "^10.1.4", + "@storybook/react-vite": "^10.1.4", + "@vituum/vite-plugin-twig": "^1.1.0", "autoprefixer": "^10.4.21", - "babel-loader": "^10.0.0", "babel-preset-minify": "^0.5.2", - "bem-twig-extension": "^0.1.1", - "breakpoint-sass": "^3.0.0", - "clean-webpack-plugin": "^4.0.0", "concurrently": "^9.2.1", - "copy-webpack-plugin": "^14.0.0", - "css-loader": "^7.1.1", - "eslint": "^10.1.0", + "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", - "eslint-plugin-jest": "^29.15.1", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-jest": "^29.0.1", "eslint-plugin-prettier": "^5.5.4", "eslint-plugin-security": "^4.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^11.3.2", + "eslint-plugin-storybook": "^10.1.4", + "fs-extra": "^11.3.1", "glob": "^13.0.6", "graceful-fs": "^4.2.11", - "html-webpack-plugin": "^5.6.4", - "image-minimizer-webpack-plugin": "^5.0.0", - "imagemin": "^9.0.1", - "imagemin-jpegtran": "^8.0.0", - "imagemin-optipng": "^8.0.0", "jest": "^30.2.0", "jest-environment-jsdom": "^30.2.0", "js-yaml": "^4.1.0", - "js-yaml-loader": "^1.2.2", - "mini-css-extract-plugin": "^2.9.4", - "node-sass-glob-importer": "^5.3.3", "normalize.css": "^8.0.1", "open-cli": "^9.0.0", "pa11y": "^9.0.1", - "postcss": "^8.5.6", - "postcss-loader": "^8.2.0", + "postcss": "^8.5.4", "postcss-scss": "^4.0.9", "ramda": "^0.32.0", "regenerator-runtime": "^0.14.1", "sass": "^1.93.2", - "sass-loader": "^16.0.6", - "storybook": "^9.1.20", - "style-dictionary": "^5.1.1", - "stylelint": "^17.7.0", + "storybook": "^10.1.4", + "stylelint": "^17.12.0", "stylelint-config-standard-scss": "^17.0.0", "stylelint-prettier": "^5.0.3", - "stylelint-webpack-plugin": "^5.0.1", - "svg-spritemap-webpack-plugin": "^5.0.3", - "terser-webpack-plugin": "^5.3.9", - "token-transformer": "^0.0.33", + "stylelint-selector-bem-pattern": "^5.0.0", + "twig": "^3.0.0", "twig-drupal-filters": "^3.2.0", - "twig-testing-library": "^1.2.0", - "twigjs-loader": "^1.0.3", - "webpack": "^5.102.1", - "webpack-cli": "^7.0.2", - "webpack-merge": "^6.0.1", - "webpack-remove-empty-scripts": "^1.1.1", + "vite": "^7.3.3", + "vite-plugin-sass-glob-import": "^6.0.0", + "vite-plugin-static-copy": "^4.1.0", + "vite-plugin-svg-sprite": "^0.7.0", "yaml": "^2.8.1" }, + "bin": { + "emulsify-audit": "scripts/audit.js", + "emulsify-audit-twig-stories": "scripts/audit-twig-stories.js" + }, "devDependencies": { - "@commitlint/cli": "^20.1.0", - "@commitlint/config-conventional": "^20.0.0", + "@commitlint/cli": "^21.0.1", + "@commitlint/config-conventional": "^21.0.1", "@semantic-release/changelog": "^6.0.2", "@semantic-release/commit-analyzer": "^13.0.1", "@semantic-release/git": "^10.0.1", - "@semantic-release/github": "^12.0.6", + "@semantic-release/github": "^12.0.8", "@semantic-release/release-notes-generator": "^14.1.0", - "all-contributors-cli": "^6.26.1", "husky": "^9.1.7", - "lint-staged": "^16.2.6", + "lint-staged": "^17.0.5", + "react": "^19.2.0", + "react-dom": "^19.2.0", "semantic-release": "^25.0.3" }, "engines": { "node": ">=24" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" } }, "node_modules/@actions/core": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.0.tgz", - "integrity": "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.1.tgz", + "integrity": "sha512-a6d/Nwahm9fliVGRhdhofo40HjHQasUPusmc7vBfyky+7Z+P2A1J68zyFVaNcEclc/Se+eO595oAr5nwEIoIUA==", "dev": true, "license": "MIT", "dependencies": { @@ -116,9 +105,9 @@ } }, "node_modules/@actions/http-client": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.0.tgz", - "integrity": "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.1.tgz", + "integrity": "sha512-+Nvd1ImaOZBSoPbsUtEhv+1z99H12xzncCkz0a3RuehINE81FZSe2QTj3uvAPTcJX/SCzUQHQ0D1GrPMbrPitg==", "dev": true, "license": "MIT", "dependencies": { @@ -127,9 +116,9 @@ } }, "node_modules/@actions/http-client/node_modules/undici": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz", - "integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==", + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.25.0.tgz", + "integrity": "sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==", "dev": true, "license": "MIT", "engines": { @@ -144,9 +133,9 @@ "license": "MIT" }, "node_modules/@adobe/css-tools": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", - "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.5.0.tgz", + "integrity": "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==", "license": "MIT" }, "node_modules/@asamuzakjp/css-color": { @@ -183,9 +172,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", - "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", + "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -221,6 +210,24 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/eslint-parser": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.28.6.tgz", + "integrity": "sha512-QGmsKi2PBO/MHSQk+AAgA9R6OHQr+VqnniFE0eMWZcVcfBZoA2dKn2hUsl3Csg/Plt9opRUWdY7//VXsrIlEiA==", + "license": "MIT", + "dependencies": { + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0", + "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0" + } + }, "node_modules/@babel/generator": { "version": "7.29.1", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", @@ -266,9 +273,9 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz", - "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.3.tgz", + "integrity": "sha512-RpLYy2sb51oNLjuu1iD3bwBqCBWUzjO0ocp+iaCP/lJtb2CPLcnC2Fftw+4sAzaMELGeWTgExSKADbdo0GFVzA==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", @@ -276,7 +283,7 @@ "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.28.6", + "@babel/traverse": "^7.29.0", "semver": "^6.3.1" }, "engines": { @@ -494,9 +501,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", - "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", + "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", "license": "MIT", "dependencies": { "@babel/types": "^7.29.0" @@ -554,6 +561,22 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array/-/plugin-bugfix-safari-rest-destructuring-rhs-array-7.29.3.tgz", + "integrity": "sha512-SRS46DFR4HqzUzCVgi90/xMoL+zeBDBvWdKYXSEzh79kXswNFEglUpMKxR04//dPqwYXWUBJ3mpUd933ru9Kmg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", @@ -1249,9 +1272,9 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz", - "integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==", + "version": "7.29.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.4.tgz", + "integrity": "sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==", "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.28.6", @@ -1658,18 +1681,19 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.2.tgz", - "integrity": "sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw==", + "version": "7.29.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.5.tgz", + "integrity": "sha512-/69t2aEzGKHD76DyLbHysF/QH2LJOB8iFnYO37unDTKBTubzcMRv0f3H5EiN1Q6ajOd/eB7dAInF0qdFVS06kA==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.29.0", + "@babel/compat-data": "^7.29.3", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": "^7.29.3", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.6", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", @@ -1701,7 +1725,7 @@ "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.28.6", - "@babel/plugin-transform-modules-systemjs": "^7.29.0", + "@babel/plugin-transform-modules-systemjs": "^7.29.4", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.0", "@babel/plugin-transform-new-target": "^7.27.1", @@ -1764,18 +1788,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.29.2.tgz", - "integrity": "sha512-Lc94FOD5+0aXhdb0Tdg3RUtqT6yWbI/BbFWvlaSJ3gAb9Ks+99nHRDKADVqC37er4eCB0fHyWT+y+K3QOvJKbw==", - "license": "MIT", - "dependencies": { - "core-js-pure": "^3.48.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/template": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", @@ -1837,90 +1849,13 @@ "url": "https://github.com/sponsors/Borewit" } }, - "node_modules/@bundled-es-modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@bundled-es-modules/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-Rk453EklPUPC3NRWc3VUNI/SSUjdBaFoaQvFRmNBNtMHVtOFD5AntiWg5kEE1hqcPqedYFDzxE3ZcMYPcA195w==", - "license": "ISC", - "dependencies": { - "deepmerge": "^4.3.1" - } - }, - "node_modules/@bundled-es-modules/glob": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/@bundled-es-modules/glob/-/glob-13.0.6.tgz", - "integrity": "sha512-x9nR2e1pt8LF0yLPC6yz/aUoiN7qJJwZ1znLxIXCxGyH+8BI+yO/sklBdn1+QbUyWXQBM+CjfZz3IhqtgIoDVg==", - "license": "MIT", - "dependencies": { - "buffer": "^6.0.3", - "events": "^3.3.0", - "glob": "^13.0.6", - "path": "^0.12.7", - "stream": "^0.0.3", - "string_decoder": "^1.3.0", - "url": "^0.11.4" - } - }, - "node_modules/@bundled-es-modules/glob/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==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/@bundled-es-modules/memfs": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@bundled-es-modules/memfs/-/memfs-4.17.0.tgz", - "integrity": "sha512-ykdrkEmQr9BV804yd37ikXfNnvxrwYfY9Z2/EtMHFEFadEjsQXJ1zL9bVZrKNLDtm91UdUOEHso6Aweg93K6xQ==", - "license": "Apache-2.0", - "dependencies": { - "assert": "^2.1.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "memfs": "^4.17.0", - "path": "^0.12.7", - "stream": "^0.0.3", - "util": "^0.12.5" - } - }, - "node_modules/@bundled-es-modules/memfs/node_modules/memfs": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.57.1.tgz", - "integrity": "sha512-WvzrWPwMQT+PtbX2Et64R4qXKK0fj/8pO85MrUCzymX3twwCiJCdvntW3HdhG1teLJcHDDLIKx5+c3HckWYZtQ==", - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/fs-core": "4.57.1", - "@jsonjoy.com/fs-fsa": "4.57.1", - "@jsonjoy.com/fs-node": "4.57.1", - "@jsonjoy.com/fs-node-builtins": "4.57.1", - "@jsonjoy.com/fs-node-to-fsa": "4.57.1", - "@jsonjoy.com/fs-node-utils": "4.57.1", - "@jsonjoy.com/fs-print": "4.57.1", - "@jsonjoy.com/fs-snapshot": "4.57.1", - "@jsonjoy.com/json-pack": "^1.11.0", - "@jsonjoy.com/util": "^1.9.0", - "glob-to-regex.js": "^1.0.1", - "thingies": "^2.5.0", - "tree-dump": "^1.0.3", - "tslib": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, "node_modules/@cacheable/memory": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.0.8.tgz", - "integrity": "sha512-FvEb29x5wVwu/Kf93IWwsOOEuhHh6dYCJF3vcKLzXc0KXIW181AOzv6ceT4ZpBHDvAfG60eqb+ekmrnLHIy+jw==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.0.9.tgz", + "integrity": "sha512-HdMx6DoGywB30vacDbBsITbIX4pgFqj1zsrV58jZBUw3klzkNoXhj7qOqAgledhxG7YZI5rBSJg7Zp8/VG0DuA==", "license": "MIT", "dependencies": { - "@cacheable/utils": "^2.4.0", + "@cacheable/utils": "^2.4.1", "@keyv/bigmap": "^1.3.1", "hookified": "^1.15.1", "keyv": "^5.6.0" @@ -1982,115 +1917,111 @@ } }, "node_modules/@commitlint/cli": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-20.5.0.tgz", - "integrity": "sha512-yNkyN/tuKTJS3wdVfsZ2tXDM4G4Gi7z+jW54Cki8N8tZqwKBltbIvUUrSbT4hz1bhW/h0CdR+5sCSpXD+wMKaQ==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-21.0.1.tgz", + "integrity": "sha512-8vq10krmbJwBkvzXKhbs4o4JQEVscd3pqOlWuDUaDBwbeL694/P33UC29tZQFTAgPU9fVJ2+f2m3zw16yKWxHg==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/format": "^20.5.0", - "@commitlint/lint": "^20.5.0", - "@commitlint/load": "^20.5.0", - "@commitlint/read": "^20.5.0", - "@commitlint/types": "^20.5.0", + "@commitlint/format": "^21.0.1", + "@commitlint/lint": "^21.0.1", + "@commitlint/load": "^21.0.1", + "@commitlint/read": "^21.0.1", + "@commitlint/types": "^21.0.1", "tinyexec": "^1.0.0", - "yargs": "^17.0.0" + "yargs": "^18.0.0" }, "bin": { "commitlint": "cli.js" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/config-conventional": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-20.5.0.tgz", - "integrity": "sha512-t3Ni88rFw1XMa4nZHgOKJ8fIAT9M2j5TnKyTqJzsxea7FUetlNdYFus9dz+MhIRZmc16P0PPyEfh6X2d/qw8SA==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-21.0.1.tgz", + "integrity": "sha512-gRorrkfWOh/+V5X8GYWWbQvrzPczopGMS4CCNrQdHkK4xWElv82BDvIsDhJZWTlI7TazOlYea6VATufCsFs+sw==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^20.5.0", + "@commitlint/types": "^21.0.1", "conventional-changelog-conventionalcommits": "^9.2.0" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/config-validator": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-20.5.0.tgz", - "integrity": "sha512-T/Uh6iJUzyx7j35GmHWdIiGRQB+ouZDk0pwAaYq4SXgB54KZhFdJ0vYmxiW6AMYICTIWuyMxDBl1jK74oFp/Gw==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-21.0.1.tgz", + "integrity": "sha512-Zd2UFdndeMMaW2O96HK0tdfT4gOImUvidMpAd/pws2zZ4m1nrAZ/9b/v2JYuE8fs86GpXv9F7LNaIuCIWhY+pA==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^20.5.0", + "@commitlint/types": "^21.0.1", "ajv": "^8.11.0" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/ensure": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-20.5.0.tgz", - "integrity": "sha512-IpHqAUesBeW1EDDdjzJeaOxU9tnogLAyXLRBn03SHlj1SGENn2JGZqSWGkFvBJkJzfXAuCNtsoYzax+ZPS+puw==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-21.0.1.tgz", + "integrity": "sha512-jJ1037967wU7YN/xkv+iRlOBlmaOXPhPO5KQSqya6GyXzBlwuLzELBFao16DVg9dZyqmNrhewzwZ3SAibetHBQ==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^20.5.0", - "lodash.camelcase": "^4.3.0", - "lodash.kebabcase": "^4.1.1", - "lodash.snakecase": "^4.1.1", - "lodash.startcase": "^4.4.0", - "lodash.upperfirst": "^4.3.1" + "@commitlint/types": "^21.0.1", + "es-toolkit": "^1.46.0" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/execute-rule": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-20.0.0.tgz", - "integrity": "sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-21.0.1.tgz", + "integrity": "sha512-RifH+FmImozKBE6mozhF4K3r2RRKP7SMi/Q/zLCmExtp5e05lhHOUYqGBlFBAGNHaZxU/WYw1XuugYK9jQzqnA==", "dev": true, "license": "MIT", "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/format": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-20.5.0.tgz", - "integrity": "sha512-TI9EwFU/qZWSK7a5qyXMpKPPv3qta7FO4tKW+Wt2al7sgMbLWTsAcDpX1cU8k16TRdsiiet9aOw0zpvRXNJu7Q==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-21.0.1.tgz", + "integrity": "sha512-ksmG2+cHGtuDPQQbhBbC4unwm444+6TiPw0d1bKf67hntgZqZ8E0g1MuYKUuyT5IH4IMmXZhKq22/Z3jBvtQIw==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^20.5.0", + "@commitlint/types": "^21.0.1", "picocolors": "^1.1.1" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/is-ignored": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-20.5.0.tgz", - "integrity": "sha512-JWLarAsurHJhPozbuAH6GbP4p/hdOCoqS9zJMfqwswne+/GPs5V0+rrsfOkP68Y8PSLphwtFXV0EzJ+GTXTTGg==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-21.0.1.tgz", + "integrity": "sha512-iNDP8SFdw8JEkM0CHZ2XFnhTN4Zg5jKUY2d8kBOSFrI2aA+3YJI7fcqVpfgbpJ9xtxFVYpi+DBATU5AvhoTq8g==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^20.5.0", + "@commitlint/types": "^21.0.1", "semver": "^7.6.0" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/is-ignored/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", "dev": true, "license": "ISC", "bin": { @@ -2101,145 +2032,143 @@ } }, "node_modules/@commitlint/lint": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-20.5.0.tgz", - "integrity": "sha512-jiM3hNUdu04jFBf1VgPdjtIPvbuVfDTBAc6L98AWcoLjF5sYqkulBHBzlVWll4rMF1T5zeQFB6r//a+s+BBKlA==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-21.0.1.tgz", + "integrity": "sha512-gF+iYtUw1gBG3HUH9z3VxwUjGg2R2G5j+nmvPs8aIeYkiB7TtneBu3wO85I0bUl93bYNsvsCNI9Nte2fmDUMww==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/is-ignored": "^20.5.0", - "@commitlint/parse": "^20.5.0", - "@commitlint/rules": "^20.5.0", - "@commitlint/types": "^20.5.0" + "@commitlint/is-ignored": "^21.0.1", + "@commitlint/parse": "^21.0.1", + "@commitlint/rules": "^21.0.1", + "@commitlint/types": "^21.0.1" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/load": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-20.5.0.tgz", - "integrity": "sha512-sLhhYTL/KxeOTZjjabKDhwidGZan84XKK1+XFkwDYL/4883kIajcz/dZFAhBJmZPtL8+nBx6bnkzA95YxPeDPw==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-21.0.1.tgz", + "integrity": "sha512-Btg1q1mKmiihN4W3x0EsPDrJMOQfMa9NIqlzlJyXAfxvsOGdGXOW5p3R3RcSxDCaY7JabY9flIl+Om1af3PSrw==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/config-validator": "^20.5.0", - "@commitlint/execute-rule": "^20.0.0", - "@commitlint/resolve-extends": "^20.5.0", - "@commitlint/types": "^20.5.0", + "@commitlint/config-validator": "^21.0.1", + "@commitlint/execute-rule": "^21.0.1", + "@commitlint/resolve-extends": "^21.0.1", + "@commitlint/types": "^21.0.1", "cosmiconfig": "^9.0.1", "cosmiconfig-typescript-loader": "^6.1.0", + "es-toolkit": "^1.46.0", "is-plain-obj": "^4.1.0", - "lodash.mergewith": "^4.6.2", "picocolors": "^1.1.1" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/message": { - "version": "20.4.3", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-20.4.3.tgz", - "integrity": "sha512-6akwCYrzcrFcTYz9GyUaWlhisY4lmQ3KvrnabmhoeAV8nRH4dXJAh4+EUQ3uArtxxKQkvxJS78hNX2EU3USgxQ==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-21.0.1.tgz", + "integrity": "sha512-R3dVQeJQ0B6yqrZEjkUHD4r7UJYLV9Lvk2xs3PTOmtWk2G3mI6Xgc+YdRxL1PwcDfBiUjv2SkIkW4AUc976w1w==", "dev": true, "license": "MIT", "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/parse": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-20.5.0.tgz", - "integrity": "sha512-SeKWHBMk7YOTnnEWUhx+d1a9vHsjjuo6Uo1xRfPNfeY4bdYFasCH1dDpAv13Lyn+dDPOels+jP6D2GRZqzc5fA==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-21.0.1.tgz", + "integrity": "sha512-oh/nCSOqdoeQNA1tO8aAmxkq5EBo8/NzcFQRvv66AWc9HpED28sL2iSicCKU6hPintWuscL6BJEWi77Wq1LPMQ==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^20.5.0", + "@commitlint/types": "^21.0.1", "conventional-changelog-angular": "^8.2.0", "conventional-commits-parser": "^6.3.0" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/read": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-20.5.0.tgz", - "integrity": "sha512-JDEIJ2+GnWpK8QqwfmW7O42h0aycJEWNqcdkJnyzLD11nf9dW2dWLTVEa8Wtlo4IZFGLPATjR5neA5QlOvIH1w==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-21.0.1.tgz", + "integrity": "sha512-pMEu4lbpC8W0ZgKJj2U6WaobXIZWdFlULpIEewYhkPXx+WZcnoO53YrVPc7QErQuNolq2Me8dP58Wu7YAVXVOA==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/top-level": "^20.4.3", - "@commitlint/types": "^20.5.0", + "@commitlint/top-level": "^21.0.1", + "@commitlint/types": "^21.0.1", "git-raw-commits": "^5.0.0", - "minimist": "^1.2.8", "tinyexec": "^1.0.0" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/resolve-extends": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-20.5.0.tgz", - "integrity": "sha512-3SHPWUW2v0tyspCTcfSsYml0gses92l6TlogwzvM2cbxDgmhSRc+fldDjvGkCXJrjSM87BBaWYTPWwwyASZRrg==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-21.0.1.tgz", + "integrity": "sha512-0DhjYWL6uYrY16Efa032fYk3woGJDU4AGWiG1XXltT9AMUNYKyb5cIZU2ivbaMZ3+kKFqUjikD2cjh66Sbh/Sg==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/config-validator": "^20.5.0", - "@commitlint/types": "^20.5.0", - "global-directory": "^4.0.1", - "import-meta-resolve": "^4.0.0", - "lodash.mergewith": "^4.6.2", + "@commitlint/config-validator": "^21.0.1", + "@commitlint/types": "^21.0.1", + "es-toolkit": "^1.46.0", + "global-directory": "^5.0.0", "resolve-from": "^5.0.0" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/rules": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-20.5.0.tgz", - "integrity": "sha512-5NdQXQEdnDPT5pK8O39ZA7HohzPRHEsDGU23cyVCNPQy4WegAbAwrQk3nIu7p2sl3dutPk8RZd91yKTrMTnRkQ==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-21.0.1.tgz", + "integrity": "sha512-VMooYpz4nJg7xlaUso6CCOWEz8D/ChkvsvZUMARcoJ1ZpfKPyFCGrHNha2tbsETNAb6ErgiRuCr2DvghrvPDYQ==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/ensure": "^20.5.0", - "@commitlint/message": "^20.4.3", - "@commitlint/to-lines": "^20.0.0", - "@commitlint/types": "^20.5.0" + "@commitlint/ensure": "^21.0.1", + "@commitlint/message": "^21.0.1", + "@commitlint/to-lines": "^21.0.1", + "@commitlint/types": "^21.0.1" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/to-lines": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-20.0.0.tgz", - "integrity": "sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-21.0.1.tgz", + "integrity": "sha512-bd1BFII7p1EQZre9Kaj+kKaMFP3cFCdt21K7DItVux9XP5WjLgJ0/Uy1pJJh9aPwVJ6SKg62PxqlZaHI8hQAXw==", "dev": true, "license": "MIT", "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/top-level": { - "version": "20.4.3", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-20.4.3.tgz", - "integrity": "sha512-qD9xfP6dFg5jQ3NMrOhG0/w5y3bBUsVGyJvXxdWEwBm8hyx4WOk3kKXw28T5czBYvyeCVJgJJ6aoJZUWDpaacQ==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-21.0.1.tgz", + "integrity": "sha512-4esUYqzY7K0FCgcJ/1xWEZekV7Ch4yZT1+xjEb7KzqbJ05XEkxHVsTfC8ADKNNtlCE2pj98KEbPGZWw9WwEnVw==", "dev": true, "license": "MIT", "dependencies": { "escalade": "^3.2.0" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/types": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-20.5.0.tgz", - "integrity": "sha512-ZJoS8oSq2CAZEpc/YI9SulLrdiIyXeHb/OGqGrkUP6Q7YV+0ouNAa7GjqRdXeQPncHQIDz/jbCTlHScvYvO/gA==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-21.0.1.tgz", + "integrity": "sha512-4u7w8jcoCUFWhjWnASYzZHAP34OqOtuFBN87nQmFvqda03YU0T6z+yB4w0gSAMpekiRqqGk5rt+qSlW+a2vSEg==", "dev": true, "license": "MIT", "dependencies": { @@ -2247,7 +2176,7 @@ "picocolors": "^1.1.1" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@conventional-changelog/git-client": { @@ -2278,9 +2207,9 @@ } }, "node_modules/@conventional-changelog/git-client/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", "dev": true, "license": "ISC", "bin": { @@ -2382,9 +2311,9 @@ } }, "node_modules/@csstools/css-syntax-patches-for-csstree": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.2.tgz", - "integrity": "sha512-5GkLzz4prTIpoyeUiIu3iV6CSG3Plo7xRVOFPKI7FVEJ3mZ0A8SwK0XU3Gl7xAkiQ+mDyam+NNp875/C5y+jSA==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.4.tgz", + "integrity": "sha512-wgsqt92b7C7tQhIdPNxj0n9zuUbQlvAuI1exyzeNrOKOi62SD7ren8zqszmpVREjAOqg8cD2FqYhQfAuKjk4sw==", "funding": [ { "type": "github", @@ -2468,15 +2397,6 @@ "postcss-selector-parser": "^7.1.1" } }, - "node_modules/@discoveryjs/json-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-1.0.0.tgz", - "integrity": "sha512-dDlz3W405VMFO4w5kIP9DOmELBcvFQGmLoKSdIRstBDubKFYwaNHV1NnlzMCQpXQFGWVALmeMORAuiLx18AvZQ==", - "license": "MIT", - "engines": { - "node": ">=14.17.0" - } - }, "node_modules/@emnapi/core": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", @@ -2555,9 +2475,9 @@ "license": "MIT" }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", "cpu": [ "ppc64" ], @@ -2571,9 +2491,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", "cpu": [ "arm" ], @@ -2587,9 +2507,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", "cpu": [ "arm64" ], @@ -2603,9 +2523,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", "cpu": [ "x64" ], @@ -2619,9 +2539,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", "cpu": [ "arm64" ], @@ -2635,9 +2555,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", "cpu": [ "x64" ], @@ -2651,9 +2571,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", "cpu": [ "arm64" ], @@ -2667,9 +2587,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", "cpu": [ "x64" ], @@ -2683,9 +2603,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", "cpu": [ "arm" ], @@ -2699,9 +2619,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", "cpu": [ "arm64" ], @@ -2715,9 +2635,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", "cpu": [ "ia32" ], @@ -2731,9 +2651,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", "cpu": [ "loong64" ], @@ -2747,9 +2667,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", "cpu": [ "mips64el" ], @@ -2763,9 +2683,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", "cpu": [ "ppc64" ], @@ -2779,9 +2699,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", "cpu": [ "riscv64" ], @@ -2795,9 +2715,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", "cpu": [ "s390x" ], @@ -2811,9 +2731,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", "cpu": [ "x64" ], @@ -2827,9 +2747,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", "cpu": [ "arm64" ], @@ -2843,9 +2763,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", "cpu": [ "x64" ], @@ -2859,9 +2779,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", "cpu": [ "arm64" ], @@ -2875,9 +2795,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", "cpu": [ "x64" ], @@ -2891,9 +2811,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", "cpu": [ "arm64" ], @@ -2907,9 +2827,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", "cpu": [ "x64" ], @@ -2923,9 +2843,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", "cpu": [ "arm64" ], @@ -2939,9 +2859,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", "cpu": [ "ia32" ], @@ -2955,9 +2875,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", "cpu": [ "x64" ], @@ -3010,107 +2930,157 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.23.5", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", - "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^3.0.5", + "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", - "minimatch": "^10.2.4" + "minimatch": "^3.1.5" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/config-helpers": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.5.tgz", - "integrity": "sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^1.2.1" + "@eslint/core": "^0.17.0" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", - "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/js": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", - "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "node_modules/@eslint/eslintrc": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "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.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://eslint.org/donate" + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "peerDependencies": { - "eslint": "^10.0.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/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==", + "license": "MIT" + }, + "node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } + "funding": { + "url": "https://eslint.org/donate" } }, "node_modules/@eslint/object-schema": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", - "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "license": "Apache-2.0", "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/plugin-kit": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.1.tgz", - "integrity": "sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^1.2.1", + "@eslint/core": "^0.17.0", "levn": "^0.4.1" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.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==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, "engines": { "node": ">=18.18.0" } }, "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", "license": "Apache-2.0", "dependencies": { - "@humanfs/core": "^0.19.1", + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", "@humanwhocodes/retry": "^0.4.0" }, "engines": { "node": ">=18.18.0" } }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -3228,72 +3198,64 @@ } }, "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==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jest/console": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.3.0.tgz", - "integrity": "sha512-PAwCvFJ4696XP2qZj+LAn1BWjZaJ6RjG6c7/lkMaUJnkyMS34ucuIsfqYvfskVNvUI27R/u4P1HMYFnlVXG/Ww==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.4.1.tgz", + "integrity": "sha512-v3bhyxUh9Hgmo5p6hAOXe14/R3ZxZDOsvHleh4B07z3m/x4/ngPUXEm9XwK4sF4u+f+P2ORb0Ge+MgpaqRMVDA==", "license": "MIT", "dependencies": { - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@types/node": "*", "chalk": "^4.1.2", - "jest-message-util": "30.3.0", - "jest-util": "30.3.0", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", "slash": "^3.0.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/console/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.3.0.tgz", - "integrity": "sha512-U5mVPsBxLSO6xYbf+tgkymLx+iAhvZX43/xI1+ej2ZOPnPdkdO1CzDmFKh2mZBn2s4XZixszHeQnzp1gm/DIxw==", + "node_modules/@jest/core": { + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.4.2.tgz", + "integrity": "sha512-TZJA6cPJUFxoWhxaLo8t0VX/MZX2wPWr0uIDvLSHIvN4gu9h02vSzqI2kBADG1ExqQlC+cY09xKMSreivvrChQ==", "license": "MIT", "dependencies": { - "@jest/console": "30.3.0", - "@jest/pattern": "30.0.1", - "@jest/reporters": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", + "@jest/console": "30.4.1", + "@jest/pattern": "30.4.0", + "@jest/reporters": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "ci-info": "^4.2.0", "exit-x": "^0.2.2", + "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-changed-files": "30.3.0", - "jest-config": "30.3.0", - "jest-haste-map": "30.3.0", - "jest-message-util": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.3.0", - "jest-resolve-dependencies": "30.3.0", - "jest-runner": "30.3.0", - "jest-runtime": "30.3.0", - "jest-snapshot": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", - "jest-watcher": "30.3.0", - "pretty-format": "30.3.0", + "jest-changed-files": "30.4.1", + "jest-config": "30.4.2", + "jest-haste-map": "30.4.1", + "jest-message-util": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-resolve-dependencies": "30.4.2", + "jest-runner": "30.4.2", + "jest-runtime": "30.4.2", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", + "jest-watcher": "30.4.1", + "pretty-format": "30.4.1", "slash": "^3.0.0" }, "engines": { @@ -3308,52 +3270,43 @@ } } }, - "node_modules/@jest/core/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/diff-sequences": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", - "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz", + "integrity": "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==", "license": "MIT", "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/environment": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.3.0.tgz", - "integrity": "sha512-SlLSF4Be735yQXyh2+mctBOzNDx5s5uLv88/j8Qn1wH679PDcwy67+YdADn8NJnGjzlXtN62asGH/T4vWOkfaw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.4.1.tgz", + "integrity": "sha512-AK9yNRqgKxiabqMoe4oW+3/TSSeV8vkdC7BGaxZdU0AFXfOpofTLqdru2GXKZghP3sdgwE9XXpnVwfZ8JnFV4w==", "license": "MIT", "dependencies": { - "@jest/fake-timers": "30.3.0", - "@jest/types": "30.3.0", + "@jest/fake-timers": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "jest-mock": "30.3.0" + "jest-mock": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/environment-jsdom-abstract": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.3.0.tgz", - "integrity": "sha512-0hNFs5N6We3DMCwobzI0ydhkY10sT1tZSC0AAiy+0g2Dt/qEWgrcV5BrMxPczhe41cxW4qm6X+jqZaUdpZIajA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.4.1.tgz", + "integrity": "sha512-dSlKrqug3siYNHVnjwIldShY12wAH3spwRltO/+8VOjg0X+xEq7vOs3DbBs4LRKsu7OH+NUb9kuZUNBF9Ho3TA==", "license": "MIT", "dependencies": { - "@jest/environment": "30.3.0", - "@jest/fake-timers": "30.3.0", - "@jest/types": "30.3.0", + "@jest/environment": "30.4.1", + "@jest/fake-timers": "30.4.1", + "@jest/types": "30.4.1", "@types/jsdom": "^21.1.7", "@types/node": "*", - "jest-mock": "30.3.0", - "jest-util": "30.3.0" + "jest-mock": "30.4.1", + "jest-util": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -3369,22 +3322,22 @@ } }, "node_modules/@jest/expect": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.3.0.tgz", - "integrity": "sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.4.1.tgz", + "integrity": "sha512-ginrj6TMgh2GshLUGCjO94Ptx9HhdZA/I6A9iUfyeLKFtdAjnKzHDgzgP9HYQgbxM1lbXScQ2eUBz2lGeVDPWA==", "license": "MIT", "dependencies": { - "expect": "30.3.0", - "jest-snapshot": "30.3.0" + "expect": "30.4.1", + "jest-snapshot": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.3.0.tgz", - "integrity": "sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz", + "integrity": "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==", "license": "MIT", "dependencies": { "@jest/get-type": "30.1.0" @@ -3394,17 +3347,17 @@ } }, "node_modules/@jest/fake-timers": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.3.0.tgz", - "integrity": "sha512-WUQDs8SOP9URStX1DzhD425CqbN/HxUYCTwVrT8sTVBfMvFqYt/s61EK5T05qnHu0po6RitXIvP9otZxYDzTGQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.4.1.tgz", + "integrity": "sha512-iW5umdmfPeWzehrVhugFQZqCchSCud5S1l2YT0O9ZhjRR0ExclANDZkiSBwzqtnlOn0J1JXvO+HZ6rkuyOVOgQ==", "license": "MIT", "dependencies": { - "@jest/types": "30.3.0", - "@sinonjs/fake-timers": "^15.0.0", + "@jest/types": "30.4.1", + "@sinonjs/fake-timers": "^15.4.0", "@types/node": "*", - "jest-message-util": "30.3.0", - "jest-mock": "30.3.0", - "jest-util": "30.3.0" + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-util": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -3420,44 +3373,44 @@ } }, "node_modules/@jest/globals": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.3.0.tgz", - "integrity": "sha512-+owLCBBdfpgL3HU+BD5etr1SvbXpSitJK0is1kiYjJxAAJggYMRQz5hSdd5pq1sSggfxPbw2ld71pt4x5wwViA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.4.1.tgz", + "integrity": "sha512-ZbuY4cmXC8DkxYjfvT2DbcHWL2T6vmsMhXCDcmTB2T0y0gaezBI77ufq5ZAIdcRkYZ7NEQEDg1xFeKbxUJ5v5Q==", "license": "MIT", "dependencies": { - "@jest/environment": "30.3.0", - "@jest/expect": "30.3.0", - "@jest/types": "30.3.0", - "jest-mock": "30.3.0" + "@jest/environment": "30.4.1", + "@jest/expect": "30.4.1", + "@jest/types": "30.4.1", + "jest-mock": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/pattern": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", - "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", + "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", "license": "MIT", "dependencies": { "@types/node": "*", - "jest-regex-util": "30.0.1" + "jest-regex-util": "30.4.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/reporters": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.3.0.tgz", - "integrity": "sha512-a09z89S+PkQnL055bVj8+pe2Caed2PBOaczHcXCykW5ngxX9EWx/1uAwncxc/HiU0oZqfwseMjyhxgRjS49qPw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.4.1.tgz", + "integrity": "sha512-/SnkPCzEQpUaBH81kjdEdDdo2WZl5hxw+BmLDGWjRkm8o7XlhjwsU36cqwe5PGBE5WYpBvDzRSdXx9rbGuJtNA==", "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", + "@jest/console": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@jridgewell/trace-mapping": "^0.3.25", "@types/node": "*", "chalk": "^4.1.2", @@ -3470,9 +3423,9 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^5.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "30.3.0", - "jest-util": "30.3.0", - "jest-worker": "30.3.0", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", + "jest-worker": "30.4.1", "slash": "^3.0.0", "string-length": "^4.0.2", "v8-to-istanbul": "^9.0.1" @@ -3489,19 +3442,10 @@ } } }, - "node_modules/@jest/reporters/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.34.0" @@ -3511,12 +3455,12 @@ } }, "node_modules/@jest/snapshot-utils": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.3.0.tgz", - "integrity": "sha512-ORbRN9sf5PP82v3FXNSwmO1OTDR2vzR2YTaR+E3VkSBZ8zadQE6IqYdYEeFH1NIkeB2HIGdF02dapb6K0Mj05g==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.4.1.tgz", + "integrity": "sha512-ObY4ljvQ95mt6iwKtVLetR/4yXiAgl3H4nJxhztr0MTjrN97TwDYrnCp/kF60Ec9HdhkWTHSu+Hg05aXfngpOA==", "license": "MIT", "dependencies": { - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "natural-compare": "^1.4.0" @@ -3540,13 +3484,13 @@ } }, "node_modules/@jest/test-result": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.3.0.tgz", - "integrity": "sha512-e/52nJGuD74AKTSe0P4y5wFRlaXP0qmrS17rqOMHeSwm278VyNyXE3gFO/4DTGF9w+65ra3lo3VKj0LBrzmgdQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.4.1.tgz", + "integrity": "sha512-/ZG7pgEiOmmWkN9TplKbOu4id2N5lh7FHwRwlkgBVAzGdRH+OkkQ8wX/kIxg4zmd3ZQvAL1RwL2yWsvNYYECTw==", "license": "MIT", "dependencies": { - "@jest/console": "30.3.0", - "@jest/types": "30.3.0", + "@jest/console": "30.4.1", + "@jest/types": "30.4.1", "@types/istanbul-lib-coverage": "^2.0.6", "collect-v8-coverage": "^1.0.2" }, @@ -3555,46 +3499,37 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.3.0.tgz", - "integrity": "sha512-dgbWy9b8QDlQeRZcv7LNF+/jFiiYHTKho1xirauZ7kVwY7avjFF6uTT0RqlgudB5OuIPagFdVtfFMosjVbk1eA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.4.1.tgz", + "integrity": "sha512-PeYE+4td5rKjoRPxztObrXU+H8hsjZfxKMXOcmrr34JerSyB/ROOxbbicz8B7A5j9R9VayDnVPvBmedqCsFCdw==", "license": "MIT", "dependencies": { - "@jest/test-result": "30.3.0", + "@jest/test-result": "30.4.1", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", + "jest-haste-map": "30.4.1", "slash": "^3.0.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/test-sequencer/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/transform": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.3.0.tgz", - "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz", + "integrity": "sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==", "license": "MIT", "dependencies": { "@babel/core": "^7.27.4", - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@jridgewell/trace-mapping": "^0.3.25", "babel-plugin-istanbul": "^7.0.1", "chalk": "^4.1.2", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-util": "30.3.0", + "jest-haste-map": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-util": "30.4.1", "pirates": "^4.0.7", "slash": "^3.0.0", "write-file-atomic": "^5.0.1" @@ -3603,23 +3538,14 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/transform/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/types": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.3.0.tgz", - "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", + "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", "license": "MIT", "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", + "@jest/pattern": "30.4.0", + "@jest/schemas": "30.4.1", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -3630,6 +3556,25 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, + "node_modules/@joshwooding/vite-plugin-react-docgen-typescript": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@joshwooding/vite-plugin-react-docgen-typescript/-/vite-plugin-react-docgen-typescript-0.7.0.tgz", + "integrity": "sha512-qvsTEwEFefhdirGOPnu9Wp6ChfIwy2dBCRuETU3uE+4cC+PFoxMSiiEhxk4lOluA34eARHA0OxqsEUYDqRMgeQ==", + "license": "MIT", + "dependencies": { + "glob": "^13.0.1", + "react-docgen-typescript": "^2.2.2" + }, + "peerDependencies": { + "typescript": ">= 4.3.x", + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -3659,16 +3604,6 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", - "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", @@ -3685,709 +3620,608 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jsonjoy.com/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node_modules/@keyv/serialize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", + "license": "MIT" + }, + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.1" } }, - "node_modules/@jsonjoy.com/buffers": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz", - "integrity": "sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==", - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" + "node_modules/@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "license": "MIT" + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" }, "funding": { "type": "github", - "url": "https://github.com/sponsors/streamich" + "url": "https://github.com/sponsors/Brooooooklyn" }, "peerDependencies": { - "tslib": "2" + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" } }, - "node_modules/@jsonjoy.com/codegen": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz", - "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==", - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "license": "MIT", + "dependencies": { + "eslint-scope": "5.1.1" } }, - "node_modules/@jsonjoy.com/fs-core": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.57.1.tgz", - "integrity": "sha512-YrEi/ZPmgc+GfdO0esBF04qv8boK9Dg9WpRQw/+vM8Qt3nnVIJWIa8HwZ/LXVZ0DB11XUROM8El/7yYTJX+WtA==", - "license": "Apache-2.0", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", "dependencies": { - "@jsonjoy.com/fs-node-builtins": "4.57.1", - "@jsonjoy.com/fs-node-utils": "4.57.1", - "thingies": "^2.5.0" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">= 8" } }, - "node_modules/@jsonjoy.com/fs-fsa": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.57.1.tgz", - "integrity": "sha512-ooEPvSW/HQDivPDPZMibHGKZf/QS4WRir1czGZmXmp3MsQqLECZEpN0JobrD8iV9BzsuwdIv+PxtWX9WpPLsIA==", - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/fs-core": "4.57.1", - "@jsonjoy.com/fs-node-builtins": "4.57.1", - "@jsonjoy.com/fs-node-utils": "4.57.1", - "thingies": "^2.5.0" - }, + "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==", + "license": "MIT", "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">= 8" } }, - "node_modules/@jsonjoy.com/fs-node": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.57.1.tgz", - "integrity": "sha512-3YaKhP8gXEKN+2O49GLNfNb5l2gbnCFHyAaybbA2JkkbQP3dpdef7WcUaHAulg/c5Dg4VncHsA3NWAUSZMR5KQ==", - "license": "Apache-2.0", + "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==", + "license": "MIT", "dependencies": { - "@jsonjoy.com/fs-core": "4.57.1", - "@jsonjoy.com/fs-node-builtins": "4.57.1", - "@jsonjoy.com/fs-node-utils": "4.57.1", - "@jsonjoy.com/fs-print": "4.57.1", - "@jsonjoy.com/fs-snapshot": "4.57.1", - "glob-to-regex.js": "^1.0.0", - "thingies": "^2.5.0" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">= 8" } }, - "node_modules/@jsonjoy.com/fs-node-builtins": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.57.1.tgz", - "integrity": "sha512-XHkFKQ5GSH3uxm8c3ZYXVrexGdscpWKIcMWKFQpMpMJc8gA3AwOMBJXJlgpdJqmrhPyQXxaY9nbkNeYpacC0Og==", - "license": "Apache-2.0", + "node_modules/@octokit/auth-token": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", + "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">= 20" } }, - "node_modules/@jsonjoy.com/fs-node-to-fsa": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.57.1.tgz", - "integrity": "sha512-pqGHyWWzNck4jRfaGV39hkqpY5QjRUQ/nRbNT7FYbBa0xf4bDG+TE1Gt2KWZrSkrkZZDE3qZUjYMbjwSliX6pg==", - "license": "Apache-2.0", + "node_modules/@octokit/core": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz", + "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", + "dev": true, + "license": "MIT", "dependencies": { - "@jsonjoy.com/fs-fsa": "4.57.1", - "@jsonjoy.com/fs-node-builtins": "4.57.1", - "@jsonjoy.com/fs-node-utils": "4.57.1" + "@octokit/auth-token": "^6.0.0", + "@octokit/graphql": "^9.0.3", + "@octokit/request": "^10.0.6", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "before-after-hook": "^4.0.0", + "universal-user-agent": "^7.0.0" }, "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">= 20" } }, - "node_modules/@jsonjoy.com/fs-node-utils": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.57.1.tgz", - "integrity": "sha512-vp+7ZzIB8v43G+GLXTS4oDUSQmhAsRz532QmmWBbdYA20s465JvwhkSFvX9cVTqRRAQg+vZ7zWDaIEh0lFe2gw==", - "license": "Apache-2.0", + "node_modules/@octokit/endpoint": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.3.tgz", + "integrity": "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==", + "dev": true, + "license": "MIT", "dependencies": { - "@jsonjoy.com/fs-node-builtins": "4.57.1" + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.2" }, "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">= 20" } }, - "node_modules/@jsonjoy.com/fs-print": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.57.1.tgz", - "integrity": "sha512-Ynct7ZJmfk6qoXDOKfpovNA36ITUx8rChLmRQtW08J73VOiuNsU8PB6d/Xs7fxJC2ohWR3a5AqyjmLojfrw5yw==", - "license": "Apache-2.0", + "node_modules/@octokit/graphql": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz", + "integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==", + "dev": true, + "license": "MIT", "dependencies": { - "@jsonjoy.com/fs-node-utils": "4.57.1", - "tree-dump": "^1.1.0" + "@octokit/request": "^10.0.6", + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.0" }, "engines": { - "node": ">=10.0" + "node": ">= 20" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", + "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz", + "integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" + "engines": { + "node": ">= 20" }, "peerDependencies": { - "tslib": "2" + "@octokit/core": ">=6" } }, - "node_modules/@jsonjoy.com/fs-snapshot": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.57.1.tgz", - "integrity": "sha512-/oG8xBNFMbDXTq9J7vepSA1kerS5vpgd3p5QZSPd+nX59uwodGJftI51gDYyHRpP57P3WCQf7LHtBYPqwUg2Bg==", - "license": "Apache-2.0", + "node_modules/@octokit/plugin-retry": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-8.1.0.tgz", + "integrity": "sha512-O1FZgXeiGb2sowEr/hYTr6YunGdSAFWnr2fyW39Ah85H8O33ELASQxcvOFF5LE6Tjekcyu2ms4qAzJVhSaJxTw==", + "dev": true, + "license": "MIT", "dependencies": { - "@jsonjoy.com/buffers": "^17.65.0", - "@jsonjoy.com/fs-node-utils": "4.57.1", - "@jsonjoy.com/json-pack": "^17.65.0", - "@jsonjoy.com/util": "^17.65.0" + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "bottleneck": "^2.15.3" }, "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" + "node": ">= 20" }, "peerDependencies": { - "tslib": "2" + "@octokit/core": ">=7" } }, - "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.67.0.tgz", - "integrity": "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==", - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" + "node_modules/@octokit/plugin-throttling": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-11.0.3.tgz", + "integrity": "sha512-34eE0RkFCKycLl2D2kq7W+LovheM/ex3AwZCYN8udpi6bxsyjZidb2McXs69hZhLmJlDqTSP8cH+jSRpiaijBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0", + "bottleneck": "^2.15.3" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" + "engines": { + "node": ">= 20" }, "peerDependencies": { - "tslib": "2" + "@octokit/core": "^7.0.0" } }, - "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/codegen": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.67.0.tgz", - "integrity": "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==", - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-17.67.0.tgz", - "integrity": "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==", - "license": "Apache-2.0", + "node_modules/@octokit/request": { + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.9.tgz", + "integrity": "sha512-o8Bi3f608eyM+7BmBiUWxFsdjLb3/ym1cQek5LZOv9KkZcxRrHCPhhRzm6xjO6HVZ85ItD6+sTsjxo821SVa/A==", + "dev": true, + "license": "MIT", "dependencies": { - "@jsonjoy.com/base64": "17.67.0", - "@jsonjoy.com/buffers": "17.67.0", - "@jsonjoy.com/codegen": "17.67.0", - "@jsonjoy.com/json-pointer": "17.67.0", - "@jsonjoy.com/util": "17.67.0", - "hyperdyperid": "^1.2.0", - "thingies": "^2.5.0", - "tree-dump": "^1.1.0" + "@octokit/endpoint": "^11.0.3", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "content-type": "^2.0.0", + "fast-content-type-parse": "^3.0.0", + "json-with-bigint": "^3.5.3", + "universal-user-agent": "^7.0.2" }, "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">= 20" } }, - "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pointer": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-17.67.0.tgz", - "integrity": "sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==", - "license": "Apache-2.0", + "node_modules/@octokit/request-error": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz", + "integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==", + "dev": true, + "license": "MIT", "dependencies": { - "@jsonjoy.com/util": "17.67.0" + "@octokit/types": "^16.0.0" }, "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">= 20" } }, - "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.67.0.tgz", - "integrity": "sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==", - "license": "Apache-2.0", + "node_modules/@octokit/types": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", + "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", + "dev": true, + "license": "MIT", "dependencies": { - "@jsonjoy.com/buffers": "17.67.0", - "@jsonjoy.com/codegen": "17.67.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "@octokit/openapi-types": "^27.0.0" } }, - "node_modules/@jsonjoy.com/json-pack": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", - "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/base64": "^1.1.2", - "@jsonjoy.com/buffers": "^1.2.0", - "@jsonjoy.com/codegen": "^1.0.0", - "@jsonjoy.com/json-pointer": "^1.0.2", - "@jsonjoy.com/util": "^1.9.0", - "hyperdyperid": "^1.2.0", - "thingies": "^2.5.0", - "tree-dump": "^1.1.0" - }, + "node_modules/@oxc-parser/binding-android-arm-eabi": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.127.0.tgz", + "integrity": "sha512-0LC7ye4hvqbIKxAzThzvswgHLFu2AURKzYLeSVvLdu2TBOYWQDmHnTqPLeA597BcUCxiLqLsS4CJ5uoI5WYWCQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@jsonjoy.com/json-pack/node_modules/@jsonjoy.com/buffers": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", - "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", - "license": "Apache-2.0", + "node_modules/@oxc-parser/binding-android-arm64": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.127.0.tgz", + "integrity": "sha512-b5jtVTH6AU5CJXHNdj7Jj9IEiR9yVjjnwHzPJhGyHGPdcsZSzBCkS9GBbV33niRMvKthDwQRFRJfI4a+k4PvYg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@jsonjoy.com/json-pointer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", - "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/codegen": "^1.0.0", - "@jsonjoy.com/util": "^1.9.0" - }, + "node_modules/@oxc-parser/binding-darwin-arm64": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.127.0.tgz", + "integrity": "sha512-obCE8B7ISKkJidjlhv9xRGJPOSDG2Yu6PRga9Ruaz35uintHxbp1Ki/Yc71wx4rj3Edrm0a1kzG1TAwit0wFpg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@jsonjoy.com/util": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", - "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/buffers": "^1.0.0", - "@jsonjoy.com/codegen": "^1.0.0" - }, + "node_modules/@oxc-parser/binding-darwin-x64": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.127.0.tgz", + "integrity": "sha512-JL6Xb5IwPQT8rUzlpsX7E+AgfcdNklXNPFp8pjCQQ5MQOQo5rtEB2ui+3Hgg9Sn7Y9Egj6YOLLiHhLpdAe12Aw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@jsonjoy.com/util/node_modules/@jsonjoy.com/buffers": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", - "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", - "license": "Apache-2.0", + "node_modules/@oxc-parser/binding-freebsd-x64": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.127.0.tgz", + "integrity": "sha512-SDQ/3MQFw58fqQz3Z1PhSKFF3JoCF4gmlNjziDm8X02tTahCw0qJbd7FGPDKw1i4VTBZene9JPyC3mHtSvi+wA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@keyv/serialize": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", - "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", - "license": "MIT" - }, - "node_modules/@kwsites/file-exists": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "node_modules/@oxc-parser/binding-linux-arm-gnueabihf": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.127.0.tgz", + "integrity": "sha512-Av+D1MIqzV0YMGPT9we2SIZaMKD7Cxs4CvXSx/yxaWHewZjYEjScpOf5igc8IILASViw4WTnjlwUdI1KzVtDHQ==", + "cpu": [ + "arm" + ], "license": "MIT", - "dependencies": { - "debug": "^4.1.1" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@kwsites/promise-deferred": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", - "license": "MIT" - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", - "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "node_modules/@oxc-parser/binding-linux-arm-musleabihf": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.127.0.tgz", + "integrity": "sha512-Cs2fdJ8cPpFdeebj6p4dag8A4+56hPvZ0AhQQzlaLswGz1tz7bXt1nETLeorrM9+AMcWFFkqxcXwDGfTVidY8g==", + "cpu": [ + "arm" + ], "license": "MIT", "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@oxc-parser/binding-linux-arm64-gnu": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.127.0.tgz", + "integrity": "sha512-qdOfTcT6SY8gsJrrV92uyEUyjqMGPpIB5JZUG6QN5dukYd+7/j0kX6MwK1DgQj39jtUYixxPiaRUiEN1+0CXgQ==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 8" + "node": "^20.19.0 || >=22.12.0" } }, - "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==", + "node_modules/@oxc-parser/binding-linux-arm64-musl": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.127.0.tgz", + "integrity": "sha512-EoTCZneNFU/P2qrpEM+RHmQwt+CvDkyGESG6qhr7KaegXLZwePfbrkCDfAk8/rhxbDUVGsZILX+2tqPzFtoFWA==", + "cpu": [ + "arm64" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 8" + "node": "^20.19.0 || >=22.12.0" } }, - "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==", + "node_modules/@oxc-parser/binding-linux-ppc64-gnu": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.127.0.tgz", + "integrity": "sha512-zALjmZYgxFLHjXeudcDF0xFGNydTAtkAeXAr2EuC17ywCyFxcmQra4w0BMde0Yi/re4Bi4iwEoEXtYN7l6eBLQ==", + "cpu": [ + "ppc64" + ], "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 8" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@octokit/auth-token": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", - "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==", - "dev": true, + "node_modules/@oxc-parser/binding-linux-riscv64-gnu": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.127.0.tgz", + "integrity": "sha512-fPP8M6zQLS7Jz7o9d5ArUSuAuSK3e+WCYVrCpdzeCOejidtZExJ9tjhDrAd3HEPqARBCPmdpqxESPFqy44vkBQ==", + "cpu": [ + "riscv64" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 20" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@octokit/core": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz", - "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", - "dev": true, + "node_modules/@oxc-parser/binding-linux-riscv64-musl": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.127.0.tgz", + "integrity": "sha512-7IcC4Ao02oGpfnjt+X/oF4U2mllo2qoSkw5xxiXNKL9MCTsTiAC6616beOuehdxGcnz1bRoPC1RQ2f1GQDdN+g==", + "cpu": [ + "riscv64" + ], "license": "MIT", - "dependencies": { - "@octokit/auth-token": "^6.0.0", - "@octokit/graphql": "^9.0.3", - "@octokit/request": "^10.0.6", - "@octokit/request-error": "^7.0.2", - "@octokit/types": "^16.0.0", - "before-after-hook": "^4.0.0", - "universal-user-agent": "^7.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 20" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@octokit/endpoint": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.3.tgz", - "integrity": "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==", - "dev": true, + "node_modules/@oxc-parser/binding-linux-s390x-gnu": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.127.0.tgz", + "integrity": "sha512-pbXIhiNFHoqWeqDNLiJ9JkpHz1IM9k4DXa66x+1GTWMG7iLxtkXgE53iiuKSXwmk3zIYmaPVfBvgcAhS583K4Q==", + "cpu": [ + "s390x" + ], "license": "MIT", - "dependencies": { - "@octokit/types": "^16.0.0", - "universal-user-agent": "^7.0.2" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 20" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@octokit/graphql": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz", - "integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==", - "dev": true, + "node_modules/@oxc-parser/binding-linux-x64-gnu": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.127.0.tgz", + "integrity": "sha512-MYCguB9RvBvlSd6gbuNI7QwiLoCCAlGnlRJFPrzLI6U1/9wkC/WK6LtBAUln55H1Ctqw45PWmqrobKoMhsYQzQ==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@octokit/request": "^10.0.6", - "@octokit/types": "^16.0.0", - "universal-user-agent": "^7.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 20" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@octokit/openapi-types": { - "version": "27.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", - "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz", - "integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==", - "dev": true, + "node_modules/@oxc-parser/binding-linux-x64-musl": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.127.0.tgz", + "integrity": "sha512-5eY0B/bxf1xIUxb4NOTvOI3KWtBQfPWYyKAzgcrCt0mDibSZygVpO1Pz8bkeiSZ5Jj9+M09dkggG3H8I5d0Uyg==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@octokit/types": "^16.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=6" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@octokit/plugin-retry": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-8.1.0.tgz", - "integrity": "sha512-O1FZgXeiGb2sowEr/hYTr6YunGdSAFWnr2fyW39Ah85H8O33ELASQxcvOFF5LE6Tjekcyu2ms4qAzJVhSaJxTw==", - "dev": true, + "node_modules/@oxc-parser/binding-openharmony-arm64": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-openharmony-arm64/-/binding-openharmony-arm64-0.127.0.tgz", + "integrity": "sha512-Gld0ajrFTUXNtdw20fVBuTQx66FA75nIVg+//pPfR3sXkuABB4mTBhl3r9JNzrJpgW//qiwxf0nWXUWGJSL3UQ==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "@octokit/request-error": "^7.0.2", - "@octokit/types": "^16.0.0", - "bottleneck": "^2.15.3" - }, + "optional": true, + "os": [ + "openharmony" + ], "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=7" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@octokit/plugin-throttling": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-11.0.3.tgz", - "integrity": "sha512-34eE0RkFCKycLl2D2kq7W+LovheM/ex3AwZCYN8udpi6bxsyjZidb2McXs69hZhLmJlDqTSP8cH+jSRpiaijBg==", - "dev": true, + "node_modules/@oxc-parser/binding-wasm32-wasi": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.127.0.tgz", + "integrity": "sha512-T6KVD7rhLzFlwGRXMnxUFfkCZD8FHnb968wVXW1mXzgRFc5RNXOBY2mPPDZ77x5Ln76ltLMgtPg0cOkU1NSrEQ==", + "cpu": [ + "wasm32" + ], "license": "MIT", + "optional": true, "dependencies": { - "@octokit/types": "^16.0.0", - "bottleneck": "^2.15.3" + "@emnapi/core": "1.9.2", + "@emnapi/runtime": "1.9.2", + "@napi-rs/wasm-runtime": "^1.1.4" }, "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": "^7.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@octokit/request": { - "version": "10.0.8", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.8.tgz", - "integrity": "sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw==", - "dev": true, + "node_modules/@oxc-parser/binding-win32-arm64-msvc": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.127.0.tgz", + "integrity": "sha512-Ujvw4X+LD1CCGULcsQcvb4YNVoBGqt+JHgNNzGGaCImELiZLk477ifUH53gIbE7EKd933NdTi25JWEr9K2HwXw==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "@octokit/endpoint": "^11.0.3", - "@octokit/request-error": "^7.0.2", - "@octokit/types": "^16.0.0", - "fast-content-type-parse": "^3.0.0", - "json-with-bigint": "^3.5.3", - "universal-user-agent": "^7.0.2" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 20" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@octokit/request-error": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz", - "integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==", - "dev": true, + "node_modules/@oxc-parser/binding-win32-ia32-msvc": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.127.0.tgz", + "integrity": "sha512-0cwxKO7KHQQQfo4Uf4B2SQrhgm+cJaP9OvFFhx52Tkg4bezsacu83GB2/In5bC415Ueeym+kXdnge/57rbSfTw==", + "cpu": [ + "ia32" + ], "license": "MIT", - "dependencies": { - "@octokit/types": "^16.0.0" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 20" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@octokit/types": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", - "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", - "dev": true, + "node_modules/@oxc-parser/binding-win32-x64-msvc": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.127.0.tgz", + "integrity": "sha512-rOrnSQSCbhI2kowr9XxE7m9a8oQXnBHjnS6j95LxxAnEZ0+Fz20WlRXG4ondQb+ejjt2KOsa65sE6++L6kUd+w==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@octokit/openapi-types": "^27.0.0" - } - }, - "node_modules/@pa11y/html_codesniffer": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@pa11y/html_codesniffer/-/html_codesniffer-2.6.0.tgz", - "integrity": "sha512-BKA7qG8NyaIBdCBDep0hYuYoF/bEyWJprE6EEVJOPiwj80sSiIKDT8LUVd19qKhVqNZZD3QvJIdFZ35p+vAFPg==", - "license": "BSD-3-Clause", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@parcel/watcher": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", - "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", - "hasInstallScript": true, + "node_modules/@oxc-project/types": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.127.0.tgz", + "integrity": "sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==", "license": "MIT", - "optional": true, - "dependencies": { - "detect-libc": "^2.0.3", - "is-glob": "^4.0.3", - "node-addon-api": "^7.0.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">= 10.0.0" - }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.6", - "@parcel/watcher-darwin-arm64": "2.5.6", - "@parcel/watcher-darwin-x64": "2.5.6", - "@parcel/watcher-freebsd-x64": "2.5.6", - "@parcel/watcher-linux-arm-glibc": "2.5.6", - "@parcel/watcher-linux-arm-musl": "2.5.6", - "@parcel/watcher-linux-arm64-glibc": "2.5.6", - "@parcel/watcher-linux-arm64-musl": "2.5.6", - "@parcel/watcher-linux-x64-glibc": "2.5.6", - "@parcel/watcher-linux-x64-musl": "2.5.6", - "@parcel/watcher-win32-arm64": "2.5.6", - "@parcel/watcher-win32-ia32": "2.5.6", - "@parcel/watcher-win32-x64": "2.5.6" + "url": "https://github.com/sponsors/Boshen" } }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz", - "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", + "node_modules/@oxc-resolver/binding-android-arm-eabi": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-android-arm-eabi/-/binding-android-arm-eabi-11.19.1.tgz", + "integrity": "sha512-aUs47y+xyXHUKlbhqHUjBABjvycq6YSD7bpxSW7vplUmdzAlJ93yXY6ZR0c1o1x5A/QKbENCvs3+NlY8IpIVzg==", "cpu": [ - "arm64" + "arm" ], "license": "MIT", "optional": true, "os": [ "android" + ] + }, + "node_modules/@oxc-resolver/binding-android-arm64": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-android-arm64/-/binding-android-arm64-11.19.1.tgz", + "integrity": "sha512-oolbkRX+m7Pq2LNjr/kKgYeC7bRDMVTWPgxBGMjSpZi/+UskVo4jsMU3MLheZV55jL6c3rNelPl4oD60ggYmqA==", + "cpu": [ + "arm64" ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } + "license": "MIT", + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", - "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", + "node_modules/@oxc-resolver/binding-darwin-arm64": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-arm64/-/binding-darwin-arm64-11.19.1.tgz", + "integrity": "sha512-nUC6d2i3R5B12sUW4O646qD5cnMXf2oBGPLIIeaRfU9doJRORAbE2SGv4eW6rMqhD+G7nf2Y8TTJTLiiO3Q/dQ==", "cpu": [ "arm64" ], @@ -4395,19 +4229,12 @@ "optional": true, "os": [ "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } + ] }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz", - "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==", + "node_modules/@oxc-resolver/binding-darwin-x64": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-x64/-/binding-darwin-x64-11.19.1.tgz", + "integrity": "sha512-cV50vE5+uAgNcFa3QY1JOeKDSkM/9ReIcc/9wn4TavhW/itkDGrXhw9jaKnkQnGbjJ198Yh5nbX/Gr2mr4Z5jQ==", "cpu": [ "x64" ], @@ -4415,19 +4242,12 @@ "optional": true, "os": [ "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } + ] }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz", - "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==", + "node_modules/@oxc-resolver/binding-freebsd-x64": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-freebsd-x64/-/binding-freebsd-x64-11.19.1.tgz", + "integrity": "sha512-xZOQiYGFxtk48PBKff+Zwoym7ScPAIVp4c14lfLxizO2LTTTJe5sx9vQNGrBymrf/vatSPNMD4FgsaaRigPkqw==", "cpu": [ "x64" ], @@ -4435,19 +4255,12 @@ "optional": true, "os": [ "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } + ] }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz", - "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==", + "node_modules/@oxc-resolver/binding-linux-arm-gnueabihf": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-11.19.1.tgz", + "integrity": "sha512-lXZYWAC6kaGe/ky2su94e9jN9t6M0/6c+GrSlCqL//XO1cxi5lpAhnJYdyrKfm0ZEr/c7RNyAx3P7FSBcBd5+A==", "cpu": [ "arm" ], @@ -4455,19 +4268,12 @@ "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } + ] }, - "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz", - "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==", + "node_modules/@oxc-resolver/binding-linux-arm-musleabihf": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-11.19.1.tgz", + "integrity": "sha512-veG1kKsuK5+t2IsO9q0DErYVSw2azvCVvWHnfTOS73WE0STdLLB7Q1bB9WR+yHPQM76ASkFyRbogWo1GR1+WbQ==", "cpu": [ "arm" ], @@ -4475,26 +4281,236 @@ "optional": true, "os": [ "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-arm64-gnu": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-11.19.1.tgz", + "integrity": "sha512-heV2+jmXyYnUrpUXSPugqWDRpnsQcDm2AX4wzTuvgdlZfoNYO0O3W2AVpJYaDn9AG4JdM6Kxom8+foE7/BcSig==", + "cpu": [ + "arm64" ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-arm64-musl": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-musl/-/binding-linux-arm64-musl-11.19.1.tgz", + "integrity": "sha512-jvo2Pjs1c9KPxMuMPIeQsgu0mOJF9rEb3y3TdpsrqwxRM+AN6/nDDwv45n5ZrUnQMsdBy5gIabioMKnQfWo9ew==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-ppc64-gnu": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-11.19.1.tgz", + "integrity": "sha512-vLmdNxWCdN7Uo5suays6A/+ywBby2PWBBPXctWPg5V0+eVuzsJxgAn6MMB4mPlshskYbppjpN2Zg83ArHze9gQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-riscv64-gnu": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-11.19.1.tgz", + "integrity": "sha512-/b+WgR+VTSBxzgOhDO7TlMXC1ufPIMR6Vj1zN+/x+MnyXGW7prTLzU9eW85Aj7Th7CCEG9ArCbTeqxCzFWdg2w==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-riscv64-musl": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-11.19.1.tgz", + "integrity": "sha512-YlRdeWb9j42p29ROh+h4eg/OQ3dTJlpHSa+84pUM9+p6i3djtPz1q55yLJhgW9XfDch7FN1pQ/Vd6YP+xfRIuw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-s390x-gnu": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-11.19.1.tgz", + "integrity": "sha512-EDpafVOQWF8/MJynsjOGFThcqhRHy417sRyLfQmeiamJ8qVhSKAn2Dn2VVKUGCjVB9C46VGjhNo7nOPUi1x6uA==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-x64-gnu": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-gnu/-/binding-linux-x64-gnu-11.19.1.tgz", + "integrity": "sha512-NxjZe+rqWhr+RT8/Ik+5ptA3oz7tUw361Wa5RWQXKnfqwSSHdHyrw6IdcTfYuml9dM856AlKWZIUXDmA9kkiBQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-x64-musl": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-musl/-/binding-linux-x64-musl-11.19.1.tgz", + "integrity": "sha512-cM/hQwsO3ReJg5kR+SpI69DMfvNCp+A/eVR4b4YClE5bVZwz8rh2Nh05InhwI5HR/9cArbEkzMjcKgTHS6UaNw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-openharmony-arm64": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-openharmony-arm64/-/binding-openharmony-arm64-11.19.1.tgz", + "integrity": "sha512-QF080IowFB0+9Rh6RcD19bdgh49BpQHUW5TajG1qvWHvmrQznTZZjYlgE2ltLXyKY+qs4F/v5xuX1XS7Is+3qA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@oxc-resolver/binding-wasm32-wasi": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-wasm32-wasi/-/binding-wasm32-wasi-11.19.1.tgz", + "integrity": "sha512-w8UCKhX826cP/ZLokXDS6+milN8y4X7zidsAttEdWlVoamTNf6lhBJldaWr3ukTDiye7s4HRcuPEPOXNC432Vg==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.1.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-resolver/binding-win32-arm64-msvc": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-11.19.1.tgz", + "integrity": "sha512-nJ4AsUVZrVKwnU/QRdzPCCrO0TrabBqgJ8pJhXITdZGYOV28TIYystV1VFLbQ7DtAcaBHpocT5/ZJnF78YJPtQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@oxc-resolver/binding-win32-ia32-msvc": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-11.19.1.tgz", + "integrity": "sha512-EW+ND5q2Tl+a3pH81l1QbfgbF3HmqgwLfDfVithRFheac8OTcnbXt/JxqD2GbDkb7xYEqy1zNaVFRr3oeG8npA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@oxc-resolver/binding-win32-x64-msvc": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-x64-msvc/-/binding-win32-x64-msvc-11.19.1.tgz", + "integrity": "sha512-6hIU3RQu45B+VNTY4Ru8ppFwjVS/S5qwYyGhBotmjxfEKk41I2DlGtRfGJndZ5+6lneE2pwloqunlOyZuX/XAw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@pa11y/html_codesniffer": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@pa11y/html_codesniffer/-/html_codesniffer-2.6.0.tgz", + "integrity": "sha512-BKA7qG8NyaIBdCBDep0hYuYoF/bEyWJprE6EEVJOPiwj80sSiIKDT8LUVd19qKhVqNZZD3QvJIdFZ35p+vAFPg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=6" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", + "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.3", + "is-glob": "^4.0.3", + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.3" + }, "engines": { "node": ">= 10.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.6", + "@parcel/watcher-darwin-arm64": "2.5.6", + "@parcel/watcher-darwin-x64": "2.5.6", + "@parcel/watcher-freebsd-x64": "2.5.6", + "@parcel/watcher-linux-arm-glibc": "2.5.6", + "@parcel/watcher-linux-arm-musl": "2.5.6", + "@parcel/watcher-linux-arm64-glibc": "2.5.6", + "@parcel/watcher-linux-arm64-musl": "2.5.6", + "@parcel/watcher-linux-x64-glibc": "2.5.6", + "@parcel/watcher-linux-x64-musl": "2.5.6", + "@parcel/watcher-win32-arm64": "2.5.6", + "@parcel/watcher-win32-ia32": "2.5.6", + "@parcel/watcher-win32-x64": "2.5.6" } }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { + "node_modules/@parcel/watcher-android-arm64": { "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz", - "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz", + "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "linux" + "android" ], "engines": { "node": ">= 10.0.0" @@ -4504,17 +4520,17 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-linux-arm64-musl": { + "node_modules/@parcel/watcher-darwin-arm64": { "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz", - "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", + "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "linux" + "darwin" ], "engines": { "node": ">= 10.0.0" @@ -4524,17 +4540,17 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-linux-x64-glibc": { + "node_modules/@parcel/watcher-darwin-x64": { "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz", - "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz", + "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ - "linux" + "darwin" ], "engines": { "node": ">= 10.0.0" @@ -4544,17 +4560,17 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-linux-x64-musl": { + "node_modules/@parcel/watcher-freebsd-x64": { "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz", - "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz", + "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ - "linux" + "freebsd" ], "engines": { "node": ">= 10.0.0" @@ -4564,17 +4580,17 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-win32-arm64": { + "node_modules/@parcel/watcher-linux-arm-glibc": { "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz", - "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz", + "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==", "cpu": [ - "arm64" + "arm" ], "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ], "engines": { "node": ">= 10.0.0" @@ -4584,17 +4600,17 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-win32-ia32": { + "node_modules/@parcel/watcher-linux-arm-musl": { "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz", - "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz", + "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==", "cpu": [ - "ia32" + "arm" ], "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ], "engines": { "node": ">= 10.0.0" @@ -4604,17 +4620,17 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-win32-x64": { + "node_modules/@parcel/watcher-linux-arm64-glibc": { "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz", - "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz", + "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==", "cpu": [ - "x64" + "arm64" ], "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ], "engines": { "node": ">= 10.0.0" @@ -4624,33 +4640,153 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz", + "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==", + "cpu": [ + "arm64" + ], "license": "MIT", "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12" + "node": ">= 10.0.0" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@pkgr/core": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz", + "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==", + "cpu": [ + "x64" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + "node": ">= 10.0.0" }, "funding": { - "url": "https://opencollective.com/pkgr" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@pnpm/config.env-replace": { - "version": "1.1.0", + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz", + "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz", + "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz", + "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz", + "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", "dev": true, @@ -4672,6 +4808,13 @@ "node": ">=12.22.0" } }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true, + "license": "ISC" + }, "node_modules/@pnpm/npm-conf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-3.0.2.tgz", @@ -4688,9 +4831,9 @@ } }, "node_modules/@puppeteer/browsers": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.0.tgz", - "integrity": "sha512-46BZJYJjc/WwmKjsvDFykHtXrtomsCIrwYQPOP7VfMJoZY2bsDF9oROBABR3paDjDcmkUye1Pb1BqdcdiipaWA==", + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.2.tgz", + "integrity": "sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==", "license": "Apache-2.0", "dependencies": { "debug": "^4.4.3", @@ -4708,10 +4851,24 @@ "node": ">=18" } }, + "node_modules/@puppeteer/browsers/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@puppeteer/browsers/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -4720,3995 +4877,1059 @@ "node": ">=10" } }, - "node_modules/@sec-ant/readable-stream": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", - "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", - "license": "MIT" - }, - "node_modules/@semantic-release/changelog": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-6.0.3.tgz", - "integrity": "sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==", - "dev": true, + "node_modules/@puppeteer/browsers/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==", "license": "MIT", "dependencies": { - "@semantic-release/error": "^3.0.0", - "aggregate-error": "^3.0.0", - "fs-extra": "^11.0.0", - "lodash": "^4.17.4" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=14.17" + "node": ">=10" }, - "peerDependencies": { - "semantic-release": ">=18.0.0" + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/@semantic-release/commit-analyzer": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-13.0.1.tgz", - "integrity": "sha512-wdnBPHKkr9HhNhXOhZD5a2LNl91+hs8CC2vsAVYxtZH3y0dV3wKn+uZSN61rdJQZ8EGxzWB3inWocBHV9+u/CQ==", - "dev": true, + "node_modules/@puppeteer/browsers/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "license": "MIT", "dependencies": { - "conventional-changelog-angular": "^8.0.0", - "conventional-changelog-writer": "^8.0.0", - "conventional-commits-filter": "^5.0.0", - "conventional-commits-parser": "^6.0.0", - "debug": "^4.0.0", - "import-from-esm": "^2.0.0", - "lodash-es": "^4.17.21", - "micromatch": "^4.0.2" + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=20.8.1" - }, - "peerDependencies": { - "semantic-release": ">=20.1.0" + "node": ">=12" } }, - "node_modules/@semantic-release/error": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", - "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", - "dev": true, - "license": "MIT", + "node_modules/@puppeteer/browsers/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", "engines": { - "node": ">=14.17" + "node": ">=12" } }, - "node_modules/@semantic-release/git": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-10.0.1.tgz", - "integrity": "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==", - "dev": true, + "node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", "license": "MIT", "dependencies": { - "@semantic-release/error": "^3.0.0", - "aggregate-error": "^3.0.0", - "debug": "^4.0.0", - "dir-glob": "^3.0.0", - "execa": "^5.0.0", - "lodash": "^4.17.4", - "micromatch": "^4.0.0", - "p-reduce": "^2.0.0" + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" }, "engines": { - "node": ">=14.17" + "node": ">=14.0.0" }, "peerDependencies": { - "semantic-release": ">=18.0.0" - } - }, - "node_modules/@semantic-release/github": { - "version": "12.0.6", - "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-12.0.6.tgz", - "integrity": "sha512-aYYFkwHW3c6YtHwQF0t0+lAjlU+87NFOZuH2CvWFD0Ylivc7MwhZMiHOJ0FMpIgPpCVib/VUAcOwvrW0KnxQtA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/core": "^7.0.0", - "@octokit/plugin-paginate-rest": "^14.0.0", - "@octokit/plugin-retry": "^8.0.0", - "@octokit/plugin-throttling": "^11.0.0", - "@semantic-release/error": "^4.0.0", - "aggregate-error": "^5.0.0", - "debug": "^4.3.4", - "dir-glob": "^3.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.0", - "issue-parser": "^7.0.0", - "lodash-es": "^4.17.21", - "mime": "^4.0.0", - "p-filter": "^4.0.0", - "tinyglobby": "^0.2.14", - "undici": "^7.0.0", - "url-join": "^5.0.0" - }, - "engines": { - "node": "^22.14.0 || >= 24.10.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, - "peerDependencies": { - "semantic-release": ">=24.1.0" + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, - "node_modules/@semantic-release/github/node_modules/@semantic-release/error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", - "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", - "dev": true, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.4.tgz", + "integrity": "sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==", + "cpu": [ + "arm" + ], "license": "MIT", - "engines": { - "node": ">=18" - } + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@semantic-release/github/node_modules/aggregate-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", - "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^5.2.0", - "indent-string": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/github/node_modules/clean-stack": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.3.0.tgz", - "integrity": "sha512-9ngPTOhYGQqNVSfeJkYXHmF7AGWp4/nN5D/QqNQs3Dvxd1Kk/WpjHfNujKHYUQ/5CoGyOyFNoWSPk5afzP0QVg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "5.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/github/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/github/node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm": { - "version": "13.1.5", - "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-13.1.5.tgz", - "integrity": "sha512-Hq5UxzoatN3LHiq2rTsWS54nCdqJHlsssGERCo8WlvdfFA9LoN0vO+OuKVSjtNapIc/S8C2LBj206wKLHg62mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@actions/core": "^3.0.0", - "@semantic-release/error": "^4.0.0", - "aggregate-error": "^5.0.0", - "env-ci": "^11.2.0", - "execa": "^9.0.0", - "fs-extra": "^11.0.0", - "lodash-es": "^4.17.21", - "nerf-dart": "^1.0.0", - "normalize-url": "^9.0.0", - "npm": "^11.6.2", - "rc": "^1.2.8", - "read-pkg": "^10.0.0", - "registry-auth-token": "^5.0.0", - "semver": "^7.1.2", - "tempy": "^3.0.0" - }, - "engines": { - "node": "^22.14.0 || >= 24.10.0" - }, - "peerDependencies": { - "semantic-release": ">=20.1.0" - } - }, - "node_modules/@semantic-release/npm/node_modules/@semantic-release/error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", - "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@semantic-release/npm/node_modules/aggregate-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", - "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^5.2.0", - "indent-string": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/clean-stack": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.3.0.tgz", - "integrity": "sha512-9ngPTOhYGQqNVSfeJkYXHmF7AGWp4/nN5D/QqNQs3Dvxd1Kk/WpjHfNujKHYUQ/5CoGyOyFNoWSPk5afzP0QVg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "5.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/execa": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", - "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sindresorhus/merge-streams": "^4.0.0", - "cross-spawn": "^7.0.6", - "figures": "^6.1.0", - "get-stream": "^9.0.0", - "human-signals": "^8.0.1", - "is-plain-obj": "^4.1.0", - "is-stream": "^4.0.1", - "npm-run-path": "^6.0.0", - "pretty-ms": "^9.2.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^4.0.0", - "yoctocolors": "^2.1.1" - }, - "engines": { - "node": "^18.19.0 || >=20.5.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/@semantic-release/npm/node_modules/figures": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", - "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-unicode-supported": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/get-stream": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", - "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sec-ant/readable-stream": "^0.4.1", - "is-stream": "^4.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/hosted-git-info": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", - "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^11.1.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/@semantic-release/npm/node_modules/human-signals": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", - "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@semantic-release/npm/node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/lru-cache": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.3.tgz", - "integrity": "sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@semantic-release/npm/node_modules/normalize-package-data": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-8.0.0.tgz", - "integrity": "sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^9.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/@semantic-release/npm/node_modules/npm-run-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", - "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^4.0.0", - "unicorn-magic": "^0.3.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/parse-json": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", - "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.26.2", - "index-to-position": "^1.1.0", - "type-fest": "^4.39.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/parse-json/node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/read-pkg": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-10.1.0.tgz", - "integrity": "sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/normalize-package-data": "^2.4.4", - "normalize-package-data": "^8.0.0", - "parse-json": "^8.3.0", - "type-fest": "^5.4.4", - "unicorn-magic": "^0.4.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/read-pkg/node_modules/unicorn-magic": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", - "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@semantic-release/npm/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/@semantic-release/npm/node_modules/strip-final-newline": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", - "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/type-fest": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.5.0.tgz", - "integrity": "sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "dependencies": { - "tagged-tag": "^1.0.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/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/@semantic-release/release-notes-generator": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-14.1.0.tgz", - "integrity": "sha512-CcyDRk7xq+ON/20YNR+1I/jP7BYKICr1uKd1HHpROSnnTdGqOTburi4jcRiTYz0cpfhxSloQO3cGhnoot7IEkA==", - "dev": true, - "license": "MIT", - "dependencies": { - "conventional-changelog-angular": "^8.0.0", - "conventional-changelog-writer": "^8.0.0", - "conventional-commits-filter": "^5.0.0", - "conventional-commits-parser": "^6.0.0", - "debug": "^4.0.0", - "get-stream": "^7.0.0", - "import-from-esm": "^2.0.0", - "into-stream": "^7.0.0", - "lodash-es": "^4.17.21", - "read-package-up": "^11.0.0" - }, - "engines": { - "node": ">=20.8.1" - }, - "peerDependencies": { - "semantic-release": ">=20.1.0" - } - }, - "node_modules/@simple-git/args-pathspec": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@simple-git/args-pathspec/-/args-pathspec-1.0.2.tgz", - "integrity": "sha512-nEFVejViHUoL8wU8GTcwqrvqfUG40S5ts6S4fr1u1Ki5CklXlRDYThPVA/qurTmCYFGnaX3XpVUmICLHdvhLaA==", - "license": "MIT" - }, - "node_modules/@simple-git/argv-parser": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@simple-git/argv-parser/-/argv-parser-1.0.3.tgz", - "integrity": "sha512-NMKv9sJcSN2VvnPT9Ja7eKfGy8Q8mMFLwPTCcuZMtv3+mYcLIZflg31S/tp2XCCyiY7YAx6cgBHQ0fwA2fWHpQ==", - "license": "MIT", - "dependencies": { - "@simple-git/args-pathspec": "^1.0.2" - } - }, - "node_modules/@simple-libs/child-process-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@simple-libs/child-process-utils/-/child-process-utils-1.0.2.tgz", - "integrity": "sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@simple-libs/stream-utils": "^1.2.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://ko-fi.com/dangreen" - } - }, - "node_modules/@simple-libs/stream-utils": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@simple-libs/stream-utils/-/stream-utils-1.2.0.tgz", - "integrity": "sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://ko-fi.com/dangreen" - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", - "license": "MIT" - }, - "node_modules/@sindresorhus/is": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-6.3.1.tgz", - "integrity": "sha512-FX4MfcifwJyFOI2lPoX7PQxCqx8BG1HCho7WdiXwpEQx1Ycij0JxkfYtGK7yqNScrZGSlt6RE6sw8QYoH7eKnQ==", - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@sindresorhus/merge-streams": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", - "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.3.1.tgz", - "integrity": "sha512-oDDGPn/4jD3viZLphixgu1jwT0bqIqP25FNXC5OkWrUqHZOF4wATtSyVzluOt4DqcMqSoKMClyhUllKSxpQCng==", - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1" - } - }, - "node_modules/@storybook/addon-a11y": { - "version": "9.1.20", - "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-9.1.20.tgz", - "integrity": "sha512-VFZ34y4ApmFwIzPRs2OJrG6jtYhM5y91eCZLTlR/HMGQciKF4TdOJHjj+5vf91SOER5UDcLizXetpiUowiZSgw==", - "license": "MIT", - "dependencies": { - "@storybook/global": "^5.0.0", - "axe-core": "^4.2.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^9.1.20" - } - }, - "node_modules/@storybook/addon-links": { - "version": "9.1.20", - "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-9.1.20.tgz", - "integrity": "sha512-/fFOqTZQ0Q5JmSAVlyfEFRa0W3hAh2u7kg+OQRLVxvNZVVuW50mOxE3853tAqisw9UX8TOCN6ZflFBeeoGLYfg==", - "license": "MIT", - "dependencies": { - "@storybook/global": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^9.1.20" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - } - } - }, - "node_modules/@storybook/addon-styling-webpack": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-styling-webpack/-/addon-styling-webpack-2.0.0.tgz", - "integrity": "sha512-N8jWhWnk3/nbL4P9zl0OEV/47P0Cxn/kPzSHjdAClyDYnqj9jI6upeLsraZgIV9Ro3QSeqeIloeXb1zMasWpOw==", - "license": "MIT", - "peerDependencies": { - "storybook": "^9.0.0", - "webpack": "^5.0.0" - } - }, - "node_modules/@storybook/addon-themes": { - "version": "9.1.20", - "resolved": "https://registry.npmjs.org/@storybook/addon-themes/-/addon-themes-9.1.20.tgz", - "integrity": "sha512-GY9WKJMxbsI24CTj1PToWbjZGuXnwLasahv51wpIQC94Sn/8NxRta8K2BO2Pqb7U3sdtjH6htUasnQnaL0/ZBw==", - "license": "MIT", - "dependencies": { - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^9.1.20" - } - }, - "node_modules/@storybook/builder-webpack5": { - "version": "9.1.20", - "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-9.1.20.tgz", - "integrity": "sha512-SN8n6NgfKUD73k9RMDTp0sxHkaEuOLlUWV2VVeXUj+HjacCDLopDXSxMcLsFP5+uSHYLBk4DQiX7EsD0rx8AJw==", - "license": "MIT", - "dependencies": { - "@storybook/core-webpack": "9.1.20", - "case-sensitive-paths-webpack-plugin": "^2.4.0", - "cjs-module-lexer": "^1.2.3", - "css-loader": "^6.7.1", - "es-module-lexer": "^1.5.0", - "fork-ts-checker-webpack-plugin": "^8.0.0", - "html-webpack-plugin": "^5.5.0", - "magic-string": "^0.30.5", - "style-loader": "^3.3.1", - "terser-webpack-plugin": "^5.3.1", - "ts-dedent": "^2.0.0", - "webpack": "5", - "webpack-dev-middleware": "^6.1.2", - "webpack-hot-middleware": "^2.25.1", - "webpack-virtual-modules": "^0.6.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^9.1.20" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@storybook/builder-webpack5/node_modules/css-loader": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", - "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", - "license": "MIT", - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.1.0", - "postcss-modules-local-by-default": "^4.0.5", - "postcss-modules-scope": "^3.2.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/@storybook/builder-webpack5/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@storybook/core-webpack": { - "version": "9.1.20", - "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-9.1.20.tgz", - "integrity": "sha512-GaH54yOx2I/1HUNHdxD3+kbbEE2xoC9sp7+8HxGC0fofEiyK/nlExo0tIX4+LRXC3T7hI+alWEc9bHgkmyLJMg==", - "license": "MIT", - "dependencies": { - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^9.1.20" - } - }, - "node_modules/@storybook/global": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz", - "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==", - "license": "MIT" - }, - "node_modules/@storybook/preset-server-webpack": { - "version": "9.1.20", - "resolved": "https://registry.npmjs.org/@storybook/preset-server-webpack/-/preset-server-webpack-9.1.20.tgz", - "integrity": "sha512-tIZEb+4AAFH02nS/R+Y2P4B8aHN8KNp6bz9yRBRdtz+qE29U01ZZfNCHdsU3PMpthWl+yu52ThjZOwG1KP9oNw==", - "license": "MIT", - "dependencies": { - "@storybook/core-webpack": "9.1.20", - "safe-identifier": "^0.4.1", - "ts-dedent": "^2.0.0", - "yaml-loader": "^0.8.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^9.1.20" - } - }, - "node_modules/@storybook/server": { - "version": "9.1.20", - "resolved": "https://registry.npmjs.org/@storybook/server/-/server-9.1.20.tgz", - "integrity": "sha512-j1h4RsXmUSJnn2caNh5nfe1nBBHQ4ZhEKHz61muDrtXG0XGgWIVHopYL7wwTxRRRhkRG/ZhSVAZFm6pPigTwbA==", - "license": "MIT", - "dependencies": { - "@storybook/global": "^5.0.0", - "ts-dedent": "^2.0.0", - "yaml": "^2.3.1" - }, - "engines": { - "node": ">=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^9.1.20" - } - }, - "node_modules/@storybook/server-webpack5": { - "version": "9.1.20", - "resolved": "https://registry.npmjs.org/@storybook/server-webpack5/-/server-webpack5-9.1.20.tgz", - "integrity": "sha512-nKxWY+qgjnPiyJTAIitquSlKuCNkSBhQ9S9ijryV68CY3J6uXsdjpgAT4dPtwk0w8KbcLl7SSFLDD/IkzVAnsA==", - "license": "MIT", - "dependencies": { - "@storybook/builder-webpack5": "9.1.20", - "@storybook/preset-server-webpack": "9.1.20", - "@storybook/server": "9.1.20" - }, - "engines": { - "node": ">=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^9.1.20" - } - }, - "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==", - "license": "MIT", - "peer": true, - "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/dom/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==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/dom/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==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/dom/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==", - "license": "MIT", - "peer": true, - "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/@testing-library/dom/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==", - "license": "MIT", - "peer": true - }, - "node_modules/@testing-library/jest-dom": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", - "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", - "license": "MIT", - "dependencies": { - "@adobe/css-tools": "^4.4.0", - "aria-query": "^5.0.0", - "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.6.3", - "picocolors": "^1.1.1", - "redent": "^3.0.0" - }, - "engines": { - "node": ">=14", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", - "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", - "license": "MIT" - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=12", - "npm": ">=6" - }, - "peerDependencies": { - "@testing-library/dom": ">=7.21.4" - } - }, - "node_modules/@tokenizer/inflate": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz", - "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.3", - "token-types": "^6.1.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", - "license": "MIT" - }, - "node_modules/@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "license": "MIT" - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", - "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "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==", - "license": "MIT", - "peer": true - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.2" - } - }, - "node_modules/@types/chai": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", - "license": "MIT", - "dependencies": { - "@types/deep-eql": "*", - "assertion-error": "^2.0.1" - } - }, - "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==", - "license": "MIT" - }, - "node_modules/@types/eslint": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "license": "MIT", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/esrecurse": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", - "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", - "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==", - "license": "MIT" - }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "license": "MIT", - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jsdom": { - "version": "21.1.7", - "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz", - "integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/tough-cookie": "*", - "parse5": "^7.0.0" - } - }, - "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==", - "license": "MIT" - }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "25.6.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz", - "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", - "license": "MIT", - "dependencies": { - "undici-types": "~7.19.0" - } - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "license": "MIT" - }, - "node_modules/@types/progress": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/progress/-/progress-2.0.7.tgz", - "integrity": "sha512-iadjw02vte8qWx7U0YM++EybBha2CQLPGu9iJ97whVgJUT5Zq9MjAPYUnbfRI2Kpehimf1QjFJYxD0t8nqzu5w==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "license": "MIT" - }, - "node_modules/@types/tough-cookie": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", - "license": "MIT" - }, - "node_modules/@types/yargs": { - "version": "17.0.35", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", - "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "license": "MIT" - }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.1.tgz", - "integrity": "sha512-gfQ8fk6cxhtptek+/8ZIqw8YrRW5048Gug8Ts5IYcMLCw18iUgrZAEY/D7s4hkI0FxEfGakKuPK/XUMPzPxi5g==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.58.1", - "@typescript-eslint/types": "^8.58.1", - "debug": "^4.4.3" - }, - "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 <6.1.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.1.tgz", - "integrity": "sha512-TPYUEqJK6avLcEjumWsIuTpuYODTTDAtoMdt8ZZa93uWMTX13Nb8L5leSje1NluammvU+oI3QRr5lLXPgihX3w==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.58.1", - "@typescript-eslint/visitor-keys": "8.58.1" - }, - "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.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.1.tgz", - "integrity": "sha512-JAr2hOIct2Q+qk3G+8YFfqkqi7sC86uNryT+2i5HzMa2MPjw4qNFvtjnw1IiA1rP7QhNKVe21mSSLaSjwA1Olw==", - "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 <6.1.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.1.tgz", - "integrity": "sha512-io/dV5Aw5ezwzfPBBWLoT+5QfVtP8O7q4Kftjn5azJ88bYyp/ZMCsyW1lpKK46EXJcaYMZ1JtYj+s/7TdzmQMw==", - "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.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.1.tgz", - "integrity": "sha512-w4w7WR7GHOjqqPnvAYbazq+Y5oS68b9CzasGtnd6jIeOIeKUzYzupGTB2T4LTPSv4d+WPeccbxuneTFHYgAAWg==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.58.1", - "@typescript-eslint/tsconfig-utils": "8.58.1", - "@typescript-eslint/types": "8.58.1", - "@typescript-eslint/visitor-keys": "8.58.1", - "debug": "^4.4.3", - "minimatch": "^10.2.2", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.5.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 <6.1.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.58.1.tgz", - "integrity": "sha512-Ln8R0tmWC7pTtLOzgJzYTXSCjJ9rDNHAqTaVONF4FEi2qwce8mD9iSOxOpLFFvWp/wBFlew0mjM1L1ihYWfBdQ==", - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.58.1", - "@typescript-eslint/types": "8.58.1", - "@typescript-eslint/typescript-estree": "8.58.1" - }, - "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 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.1.tgz", - "integrity": "sha512-y+vH7QE8ycjoa0bWciFg7OpFcipUuem1ujhrdLtq1gByKwfbC7bPeKsiny9e0urg93DqwGcHey+bGRKCnF1nZQ==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.58.1", - "eslint-visitor-keys": "^5.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "license": "ISC" - }, - "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", - "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", - "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", - "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", - "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", - "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", - "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", - "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", - "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", - "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", - "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", - "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", - "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", - "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", - "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", - "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", - "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.11" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", - "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", - "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", - "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "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==", - "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==", - "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==", - "license": "MIT", - "dependencies": { - "tinyrainbow": "^2.0.0" - }, - "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==", - "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==", - "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/@webassemblyjs/ast": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", - "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", - "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.13.2", - "@webassemblyjs/helper-api-error": "1.13.2", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", - "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", - "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/wasm-gen": "1.14.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", - "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", - "license": "MIT", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", - "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", - "license": "Apache-2.0", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", - "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", - "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/helper-wasm-section": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-opt": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1", - "@webassemblyjs/wast-printer": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", - "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", - "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", - "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-api-error": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", - "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xmldom/xmldom": { - "version": "0.9.9", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.9.tgz", - "integrity": "sha512-qycIHAucxy/LXAYIjmLmtQ8q9GPnMbnjG1KXhWm9o5sCr6pOYDATkMPiTNa6/v8eELyqOQ2FsEqeoFYmgv/gJg==", - "license": "MIT", - "engines": { - "node": ">=14.6" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "license": "BSD-3-Clause" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "license": "Apache-2.0" - }, - "node_modules/@zip.js/zip.js": { - "version": "2.8.26", - "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.8.26.tgz", - "integrity": "sha512-RQ4h9F6DOiHxpdocUDrOl6xBM+yOtz+LkUol47AVWcfebGBDpZ7w7Xvz9PS24JgXvLGiXXzSAfdCdVy1tPlaFA==", - "license": "BSD-3-Clause", - "engines": { - "bun": ">=0.7.0", - "deno": ">=1.0.0", - "node": ">=18.0.0" - } - }, - "node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-phases": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", - "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", - "license": "MIT", - "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "acorn": "^8.14.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==", - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/add-attributes-twig-extension": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/add-attributes-twig-extension/-/add-attributes-twig-extension-0.1.0.tgz", - "integrity": "sha512-2zgkKRQU+7jbElXa/RqQDyu0sM9iOhsFlBlQbTJMEgKsNDAhip91raGNHkdCbZuXmRYy1PaLNjX/rk9Ecngfkw==", - "license": "MIT", - "peerDependencies": { - "twig": "^1.13.3" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/all-contributors-cli": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/all-contributors-cli/-/all-contributors-cli-6.26.1.tgz", - "integrity": "sha512-Ymgo3FJACRBEd1eE653FD1J/+uD0kqpUNYfr9zNC1Qby0LgbhDBzB3EF6uvkAbYpycStkk41J+0oo37Lc02yEw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.6", - "async": "^3.1.0", - "chalk": "^4.0.0", - "didyoumean": "^1.2.1", - "inquirer": "^7.3.3", - "json-fixer": "^1.6.8", - "lodash": "^4.11.2", - "node-fetch": "^2.6.0", - "pify": "^5.0.0", - "yargs": "^15.0.1" - }, - "bin": { - "all-contributors": "dist/cli.js" - }, - "engines": { - "node": ">=4" - }, - "optionalDependencies": { - "prettier": "^2" - } - }, - "node_modules/all-contributors-cli/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/all-contributors-cli/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/all-contributors-cli/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/all-contributors-cli/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/all-contributors-cli/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/all-contributors-cli/node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "license": "MIT", - "optional": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/all-contributors-cli/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/all-contributors-cli/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/all-contributors-cli/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/all-contributors-cli/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "engines": [ - "node >= 0.8.0" - ], - "license": "Apache-2.0", - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ansis": { - "version": "4.0.0-node10", - "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.0.0-node10.tgz", - "integrity": "sha512-BRrU0Bo1X9dFGw6KgGz6hWrqQuOlVEDOzkb0QSLZY9sXHqA7pNj7yHPVJRz7y/rj4EOJ3d/D5uxH+ee9leYgsg==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true, - "license": "MIT" - }, - "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==", - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", - "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/archive-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", - "integrity": "sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==", - "license": "MIT", - "dependencies": { - "file-type": "^4.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/archive-type/node_modules/file-type": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", - "integrity": "sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "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==", - "license": "Python-2.0" - }, - "node_modules/argv-formatter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", - "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", - "dev": true, - "license": "MIT" - }, - "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==", - "license": "Apache-2.0", - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true, - "license": "MIT" - }, - "node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "license": "MIT", - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/assert": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", - "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "is-nan": "^1.3.2", - "object-is": "^1.1.5", - "object.assign": "^4.1.4", - "util": "^0.12.5" - } - }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, - "license": "MIT" - }, - "node_modules/autoprefixer": { - "version": "10.4.27", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.27.tgz", - "integrity": "sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.28.1", - "caniuse-lite": "^1.0.30001774", - "fraction.js": "^5.3.4", - "picocolors": "^1.1.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axe-core": { - "version": "4.11.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.2.tgz", - "integrity": "sha512-byD6KPdvo72y/wj2T/4zGEvvlis+PsZsn/yPS3pEO+sFpcrqRpX/TJCxvVaEsNeMrfQbCr7w163YqoD9IYwHXw==", - "license": "MPL-2.0", - "engines": { - "node": ">=4" - } - }, - "node_modules/b4a": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz", - "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==", - "license": "Apache-2.0", - "peerDependencies": { - "react-native-b4a": "*" - }, - "peerDependenciesMeta": { - "react-native-b4a": { - "optional": true - } - } - }, - "node_modules/babel-helper-evaluate-path": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.5.0.tgz", - "integrity": "sha512-mUh0UhS607bGh5wUMAQfOpt2JX2ThXMtppHRdRU1kL7ZLRWIXxoV2UIV1r2cAeeNeU1M5SB5/RSUgUxrK8yOkA==", - "license": "MIT" - }, - "node_modules/babel-helper-flip-expressions": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.4.3.tgz", - "integrity": "sha512-rSrkRW4YQ2ETCWww9gbsWk4N0x1BOtln349Tk0dlCS90oT68WMLyGR7WvaMp3eAnsVrCqdUtC19lo1avyGPejA==", - "license": "MIT" - }, - "node_modules/babel-helper-is-nodes-equiv": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz", - "integrity": "sha512-ri/nsMFVRqXn7IyT5qW4/hIAGQxuYUFHa3qsxmPtbk6spZQcYlyDogfVpNm2XYOslH/ULS4VEJGUqQX5u7ACQw==", - "license": "MIT" - }, - "node_modules/babel-helper-is-void-0": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-helper-is-void-0/-/babel-helper-is-void-0-0.4.3.tgz", - "integrity": "sha512-07rBV0xPRM3TM5NVJEOQEkECX3qnHDjaIbFvWYPv+T1ajpUiVLiqTfC+MmiZxY5KOL/Ec08vJdJD9kZiP9UkUg==", - "license": "MIT" - }, - "node_modules/babel-helper-mark-eval-scopes": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.4.3.tgz", - "integrity": "sha512-+d/mXPP33bhgHkdVOiPkmYoeXJ+rXRWi7OdhwpyseIqOS8CmzHQXHUp/+/Qr8baXsT0kjGpMHHofHs6C3cskdA==", - "license": "MIT" - }, - "node_modules/babel-helper-remove-or-void": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.4.3.tgz", - "integrity": "sha512-eYNceYtcGKpifHDir62gHJadVXdg9fAhuZEXiRQnJJ4Yi4oUTpqpNY//1pM4nVyjjDMPYaC2xSf0I+9IqVzwdA==", - "license": "MIT" - }, - "node_modules/babel-helper-to-multiple-sequence-expressions": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.5.0.tgz", - "integrity": "sha512-m2CvfDW4+1qfDdsrtf4dwOslQC3yhbgyBFptncp4wvtdrDHqueW7slsYv4gArie056phvQFhT2nRcGS4bnm6mA==", - "license": "MIT" - }, - "node_modules/babel-jest": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.3.0.tgz", - "integrity": "sha512-gRpauEU2KRrCox5Z296aeVHR4jQ98BCnu0IO332D/xpHNOsIH/bgSRk9k6GbKIbBw8vFeN6ctuu6tV8WOyVfYQ==", - "license": "MIT", - "dependencies": { - "@jest/transform": "30.3.0", - "@types/babel__core": "^7.20.5", - "babel-plugin-istanbul": "^7.0.1", - "babel-preset-jest": "30.3.0", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "slash": "^3.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0 || ^8.0.0-0" - } - }, - "node_modules/babel-jest/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-loader": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-10.1.1.tgz", - "integrity": "sha512-JwKSzk2kjIe7mgPK+/lyZ2QAaJcpahNAdM+hgR2HI8D0OJVkdj8Rl6J3kaLYki9pwF7P2iWnD8qVv80Lq1ABtg==", - "license": "MIT", - "dependencies": { - "find-up": "^5.0.0" - }, - "engines": { - "node": "^18.20.0 || ^20.10.0 || >=22.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0 || ^8.0.0-beta.1", - "@rspack/core": "^1.0.0 || ^2.0.0-0", - "webpack": ">=5.61.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", - "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", - "license": "BSD-3-Clause", - "workspaces": [ - "test/babel-8" - ], - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-instrument": "^6.0.2", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.3.0.tgz", - "integrity": "sha512-+TRkByhsws6sfPjVaitzadk1I0F5sPvOVUH5tyTSzhePpsGIVrdeunHSw/C36QeocS95OOk8lunc4rlu5Anwsg==", - "license": "MIT", - "dependencies": { - "@types/babel__core": "^7.20.5" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/babel-plugin-minify-builtins": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.5.0.tgz", - "integrity": "sha512-wpqbN7Ov5hsNwGdzuzvFcjgRlzbIeVv1gMIlICbPj0xkexnfoIDe7q+AZHMkQmAE/F9R5jkrB6TLfTegImlXag==", - "license": "MIT" - }, - "node_modules/babel-plugin-minify-constant-folding": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.5.0.tgz", - "integrity": "sha512-Vj97CTn/lE9hR1D+jKUeHfNy+m1baNiJ1wJvoGyOBUx7F7kJqDZxr9nCHjO/Ad+irbR3HzR6jABpSSA29QsrXQ==", - "license": "MIT", - "dependencies": { - "babel-helper-evaluate-path": "^0.5.0" - } - }, - "node_modules/babel-plugin-minify-dead-code-elimination": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.5.2.tgz", - "integrity": "sha512-krq9Lwi0QIzyAlcNBXTL4usqUvevB4BzktdEsb8srcXC1AaYqRJiAQw6vdKdJSaXbz6snBvziGr6ch/aoRCfpA==", - "license": "MIT", - "dependencies": { - "babel-helper-evaluate-path": "^0.5.0", - "babel-helper-mark-eval-scopes": "^0.4.3", - "babel-helper-remove-or-void": "^0.4.3", - "lodash": "^4.17.11" - } - }, - "node_modules/babel-plugin-minify-flip-comparisons": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.4.3.tgz", - "integrity": "sha512-8hNwgLVeJzpeLVOVArag2DfTkbKodzOHU7+gAZ8mGBFGPQHK6uXVpg3jh5I/F6gfi5Q5usWU2OKcstn1YbAV7A==", - "license": "MIT", - "dependencies": { - "babel-helper-is-void-0": "^0.4.3" - } - }, - "node_modules/babel-plugin-minify-guarded-expressions": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.4.4.tgz", - "integrity": "sha512-RMv0tM72YuPPfLT9QLr3ix9nwUIq+sHT6z8Iu3sLbqldzC1Dls8DPCywzUIzkTx9Zh1hWX4q/m9BPoPed9GOfA==", - "license": "MIT", - "dependencies": { - "babel-helper-evaluate-path": "^0.5.0", - "babel-helper-flip-expressions": "^0.4.3" - } - }, - "node_modules/babel-plugin-minify-infinity": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.4.3.tgz", - "integrity": "sha512-X0ictxCk8y+NvIf+bZ1HJPbVZKMlPku3lgYxPmIp62Dp8wdtbMLSekczty3MzvUOlrk5xzWYpBpQprXUjDRyMA==", - "license": "MIT" - }, - "node_modules/babel-plugin-minify-mangle-names": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.5.1.tgz", - "integrity": "sha512-8KMichAOae2FHlipjNDTo2wz97MdEb2Q0jrn4NIRXzHH7SJ3c5TaNNBkeTHbk9WUsMnqpNUx949ugM9NFWewzw==", - "license": "MIT", - "dependencies": { - "babel-helper-mark-eval-scopes": "^0.4.3" - } - }, - "node_modules/babel-plugin-minify-numeric-literals": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.4.3.tgz", - "integrity": "sha512-5D54hvs9YVuCknfWywq0eaYDt7qYxlNwCqW9Ipm/kYeS9gYhJd0Rr/Pm2WhHKJ8DC6aIlDdqSBODSthabLSX3A==", - "license": "MIT" - }, - "node_modules/babel-plugin-minify-replace": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.5.0.tgz", - "integrity": "sha512-aXZiaqWDNUbyNNNpWs/8NyST+oU7QTpK7J9zFEFSA0eOmtUNMU3fczlTTTlnCxHmq/jYNFEmkkSG3DDBtW3Y4Q==", - "license": "MIT" - }, - "node_modules/babel-plugin-minify-simplify": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.5.1.tgz", - "integrity": "sha512-OSYDSnoCxP2cYDMk9gxNAed6uJDiDz65zgL6h8d3tm8qXIagWGMLWhqysT6DY3Vs7Fgq7YUDcjOomhVUb+xX6A==", - "license": "MIT", - "dependencies": { - "babel-helper-evaluate-path": "^0.5.0", - "babel-helper-flip-expressions": "^0.4.3", - "babel-helper-is-nodes-equiv": "^0.0.1", - "babel-helper-to-multiple-sequence-expressions": "^0.5.0" - } - }, - "node_modules/babel-plugin-minify-type-constructors": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.4.3.tgz", - "integrity": "sha512-4ADB0irJ/6BeXWHubjCJmrPbzhxDgjphBMjIjxCc25n4NGJ00NsYqwYt+F/OvE9RXx8KaSW7cJvp+iZX436tnQ==", - "license": "MIT", - "dependencies": { - "babel-helper-is-void-0": "^0.4.3" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", - "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.28.6", - "@babel/helper-define-polyfill-provider": "^0.6.8", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.2.tgz", - "integrity": "sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==", - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.8", - "core-js-compat": "^3.48.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", - "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.8" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-transform-inline-consecutive-adds": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.4.3.tgz", - "integrity": "sha512-8D104wbzzI5RlxeVPYeQb9QsUyepiH1rAO5hpPpQ6NPRgQLpIVwkS/Nbx944pm4K8Z+rx7CgjPsFACz/VCBN0Q==", - "license": "MIT" - }, - "node_modules/babel-plugin-transform-member-expression-literals": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.9.4.tgz", - "integrity": "sha512-Xq9/Rarpj+bjOZSl1nBbZYETsNEDDJSrb6Plb1sS3/36FukWFLLRysgecva5KZECjUJTrJoQqjJgtWToaflk5Q==", - "license": "MIT" - }, - "node_modules/babel-plugin-transform-merge-sibling-variables": { - "version": "6.9.5", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.9.5.tgz", - "integrity": "sha512-xj/KrWi6/uP+DrD844h66Qh2cZN++iugEIgH8QcIxhmZZPNP6VpOE9b4gP2FFW39xDAY43kCmYMM6U0QNKN8fw==", - "license": "MIT" - }, - "node_modules/babel-plugin-transform-minify-booleans": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.4.tgz", - "integrity": "sha512-9pW9ePng6DZpzGPalcrULuhSCcauGAbn8AeU3bE34HcDkGm8Ldt0ysjGkyb64f0K3T5ilV4mriayOVv5fg0ASA==", - "license": "MIT" - }, - "node_modules/babel-plugin-transform-property-literals": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.4.tgz", - "integrity": "sha512-Pf8JHTjTPxecqVyL6KSwD/hxGpoTZjiEgV7nCx0KFQsJYM0nuuoCajbg09KRmZWeZbJ5NGTySABYv8b/hY1eEA==", - "license": "MIT", - "dependencies": { - "esutils": "^2.0.2" - } - }, - "node_modules/babel-plugin-transform-regexp-constructors": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.4.3.tgz", - "integrity": "sha512-JjymDyEyRNhAoNFp09y/xGwYVYzT2nWTGrBrWaL6eCg2m+B24qH2jR0AA8V8GzKJTgC8NW6joJmc6nabvWBD/g==", - "license": "MIT" - }, - "node_modules/babel-plugin-transform-remove-console": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.9.4.tgz", - "integrity": "sha512-88blrUrMX3SPiGkT1GnvVY8E/7A+k6oj3MNvUtTIxJflFzXTw1bHkuJ/y039ouhFMp2prRn5cQGzokViYi1dsg==", - "license": "MIT" - }, - "node_modules/babel-plugin-transform-remove-debugger": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.9.4.tgz", - "integrity": "sha512-Kd+eTBYlXfwoFzisburVwrngsrz4xh9I0ppoJnU/qlLysxVBRgI4Pj+dk3X8F5tDiehp3hhP8oarRMT9v2Z3lw==", - "license": "MIT" - }, - "node_modules/babel-plugin-transform-remove-undefined": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.5.0.tgz", - "integrity": "sha512-+M7fJYFaEE/M9CXa0/IRkDbiV3wRELzA1kKQFCJ4ifhrzLKn/9VCCgj9OFmYWwBd8IB48YdgPkHYtbYq+4vtHQ==", - "license": "MIT", - "dependencies": { - "babel-helper-evaluate-path": "^0.5.0" - } - }, - "node_modules/babel-plugin-transform-simplify-comparison-operators": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.4.tgz", - "integrity": "sha512-GLInxhGAQWJ9YIdjwF6dAFlmh4U+kN8pL6Big7nkDzHoZcaDQOtBm28atEhQJq6m9GpAovbiGEShKqXv4BSp0A==", - "license": "MIT" - }, - "node_modules/babel-plugin-transform-undefined-to-void": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz", - "integrity": "sha512-D2UbwxawEY1xVc9svYAUZQM2xarwSNXue2qDIx6CeV2EuMGaes/0su78zlIDIAgE7BvnMw4UpmSo9fDy+znghg==", - "license": "MIT" - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", - "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", - "license": "MIT", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5" - }, - "peerDependencies": { - "@babel/core": "^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/babel-preset-jest": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.3.0.tgz", - "integrity": "sha512-6ZcUbWHC+dMz2vfzdNwi87Z1gQsLNK2uLuK1Q89R11xdvejcivlYYwDlEv0FHX3VwEXpbBQ9uufB/MUNpZGfhQ==", - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "30.3.0", - "babel-preset-current-node-syntax": "^1.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0 || ^8.0.0-beta.1" - } - }, - "node_modules/babel-preset-minify": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/babel-preset-minify/-/babel-preset-minify-0.5.2.tgz", - "integrity": "sha512-v4GL+kk0TfovbRIKZnC3HPbu2cAGmPAby7BsOmuPdMJfHV+4FVdsGXTH/OOGQRKYdjemBuL1+MsE6mobobhe9w==", - "license": "MIT", - "dependencies": { - "babel-plugin-minify-builtins": "^0.5.0", - "babel-plugin-minify-constant-folding": "^0.5.0", - "babel-plugin-minify-dead-code-elimination": "^0.5.2", - "babel-plugin-minify-flip-comparisons": "^0.4.3", - "babel-plugin-minify-guarded-expressions": "^0.4.4", - "babel-plugin-minify-infinity": "^0.4.3", - "babel-plugin-minify-mangle-names": "^0.5.1", - "babel-plugin-minify-numeric-literals": "^0.4.3", - "babel-plugin-minify-replace": "^0.5.0", - "babel-plugin-minify-simplify": "^0.5.1", - "babel-plugin-minify-type-constructors": "^0.4.3", - "babel-plugin-transform-inline-consecutive-adds": "^0.4.3", - "babel-plugin-transform-member-expression-literals": "^6.9.4", - "babel-plugin-transform-merge-sibling-variables": "^6.9.5", - "babel-plugin-transform-minify-booleans": "^6.9.4", - "babel-plugin-transform-property-literals": "^6.9.4", - "babel-plugin-transform-regexp-constructors": "^0.4.3", - "babel-plugin-transform-remove-console": "^6.9.4", - "babel-plugin-transform-remove-debugger": "^6.9.4", - "babel-plugin-transform-remove-undefined": "^0.5.0", - "babel-plugin-transform-simplify-comparison-operators": "^6.9.4", - "babel-plugin-transform-undefined-to-void": "^6.9.4", - "lodash": "^4.17.11" - } - }, - "node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/bare-events": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", - "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", - "license": "Apache-2.0", - "peerDependencies": { - "bare-abort-controller": "*" - }, - "peerDependenciesMeta": { - "bare-abort-controller": { - "optional": true - } - } - }, - "node_modules/bare-fs": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.0.tgz", - "integrity": "sha512-xzqKsCFxAek9aezYhjJuJRXBIaYlg/0OGDTZp+T8eYmYMlm66cs6cYko02drIyjN2CBbi+I6L7YfXyqpqtKRXA==", - "license": "Apache-2.0", - "dependencies": { - "bare-events": "^2.5.4", - "bare-path": "^3.0.0", - "bare-stream": "^2.6.4", - "bare-url": "^2.2.2", - "fast-fifo": "^1.3.2" - }, - "engines": { - "bare": ">=1.16.0" - }, - "peerDependencies": { - "bare-buffer": "*" - }, - "peerDependenciesMeta": { - "bare-buffer": { - "optional": true - } - } - }, - "node_modules/bare-os": { - "version": "3.8.7", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.8.7.tgz", - "integrity": "sha512-G4Gr1UsGeEy2qtDTZwL7JFLo2wapUarz7iTMcYcMFdS89AIQuBoyjgXZz0Utv7uHs3xA9LckhVbeBi8lEQrC+w==", - "license": "Apache-2.0", - "engines": { - "bare": ">=1.14.0" - } - }, - "node_modules/bare-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", - "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", - "license": "Apache-2.0", - "dependencies": { - "bare-os": "^3.0.1" - } - }, - "node_modules/bare-stream": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.0.tgz", - "integrity": "sha512-3zAJRZMDFGjdn+RVnNpF9kuELw+0Fl3lpndM4NcEOhb9zwtSo/deETfuIwMSE5BXanA0FrN1qVjffGwAg2Y7EA==", - "license": "Apache-2.0", - "dependencies": { - "streamx": "^2.25.0", - "teex": "^1.0.1" - }, - "peerDependencies": { - "bare-abort-controller": "*", - "bare-buffer": "*", - "bare-events": "*" - }, - "peerDependenciesMeta": { - "bare-abort-controller": { - "optional": true - }, - "bare-buffer": { - "optional": true - }, - "bare-events": { - "optional": true - } - } - }, - "node_modules/bare-url": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.0.tgz", - "integrity": "sha512-NSTU5WN+fy/L0DDenfE8SXQna4voXuW0FHM7wH8i3/q9khUSchfPbPezO4zSFMnDGIf9YE+mt/RWhZgNRKRIXA==", - "license": "Apache-2.0", - "dependencies": { - "bare-path": "^3.0.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.4.tgz", + "integrity": "sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==", + "cpu": [ + "arm64" ], - "license": "MIT" - }, - "node_modules/baseline-browser-mapping": { - "version": "2.10.17", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.17.tgz", - "integrity": "sha512-HdrkN8eVG2CXxeifv/VdJ4A4RSra1DTW8dc/hdxzhGHN8QePs6gKaWM9pHPcpCoxYZJuOZ8drHmbdpLHjCYjLA==", - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.cjs" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/basic-ftp": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.2.tgz", - "integrity": "sha512-1tDrzKsdCg70WGvbFss/ulVAxupNauGnOlgpyjKzeQxzyllBLS0CGLV7tjIXTK3ZQA9/FBEm9qyFFN1bciA6pw==", "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/before-after-hook": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", - "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", - "dev": true, - "license": "Apache-2.0" + "optional": true, + "os": [ + "android" + ] }, - "node_modules/bem-twig-extension": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bem-twig-extension/-/bem-twig-extension-0.1.1.tgz", - "integrity": "sha512-um1dGGcMJO3YKEww7lD0k7IqgkJXz5cATTDMJy34Y+0I68uMyKmlCzlKTtFq9mfCT/wZnD9N6OXBifA2qB3ilA==", + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.4.tgz", + "integrity": "sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "twig": "^1.13.3" - } + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/better-opn": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz", - "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==", + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.4.tgz", + "integrity": "sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "open": "^8.0.4" - }, - "engines": { - "node": ">=12.0.0" - } + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/better-opn/node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.4.tgz", + "integrity": "sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==", + "cpu": [ + "arm64" + ], "license": "MIT", - "engines": { - "node": ">=8" - } + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/better-opn/node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.4.tgz", + "integrity": "sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==", + "cpu": [ + "x64" + ], "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/better-opn/node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.4.tgz", + "integrity": "sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==", + "cpu": [ + "arm" + ], "license": "MIT", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/better-opn/node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.4.tgz", + "integrity": "sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==", + "cpu": [ + "arm" + ], "license": "MIT", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/bfj": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/bfj/-/bfj-9.1.3.tgz", - "integrity": "sha512-1ythbcNNAd2UjTYW6M+MAHd9KM/m3g4mQ+3a4Vom16WgmUa4GsisdmXAYfpAjkObY5zdpgzaBh1ctZOEcJipuQ==", + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.4.tgz", + "integrity": "sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "check-types": "^11.2.3", - "hoopy": "^0.1.4", - "tryer": "^1.0.1" - }, - "engines": { - "node": ">= 18.0.0" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.4.tgz", + "integrity": "sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==", + "cpu": [ + "arm64" + ], "license": "MIT", - "engines": { - "node": "*" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/bin-build": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bin-build/-/bin-build-3.0.0.tgz", - "integrity": "sha512-jcUOof71/TNAI2uM5uoUaDq2ePcVBQ3R/qhxAz1rX7UfvduAL/RXD3jXzvn8cVcDJdGVkiR1shal3OH0ImpuhA==", + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.4.tgz", + "integrity": "sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==", + "cpu": [ + "loong64" + ], "license": "MIT", - "dependencies": { - "decompress": "^4.0.0", - "download": "^6.2.2", - "execa": "^0.7.0", - "p-map-series": "^1.0.0", - "tempfile": "^2.0.0" - }, - "engines": { - "node": ">=4" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/bin-build/node_modules/cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.4.tgz", + "integrity": "sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==", + "cpu": [ + "loong64" + ], "license": "MIT", - "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/bin-build/node_modules/execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.4.tgz", + "integrity": "sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==", + "cpu": [ + "ppc64" + ], "license": "MIT", - "dependencies": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=4" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/bin-build/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.4.tgz", + "integrity": "sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==", + "cpu": [ + "ppc64" + ], "license": "MIT", - "engines": { - "node": ">=4" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/bin-build/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.4.tgz", + "integrity": "sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==", + "cpu": [ + "riscv64" + ], "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/bin-build/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "license": "ISC", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/bin-build/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.4.tgz", + "integrity": "sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==", + "cpu": [ + "riscv64" + ], "license": "MIT", - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/bin-build/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.4.tgz", + "integrity": "sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==", + "cpu": [ + "s390x" + ], "license": "MIT", - "engines": { - "node": ">=4" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/bin-build/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.4.tgz", + "integrity": "sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/bin-build/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.4.tgz", + "integrity": "sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==", + "cpu": [ + "x64" + ], "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/bin-build/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.4.tgz", + "integrity": "sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] }, - "node_modules/bin-build/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "license": "ISC" + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.4.tgz", + "integrity": "sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] }, - "node_modules/bin-check": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz", - "integrity": "sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA==", + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.4.tgz", + "integrity": "sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "execa": "^0.7.0", - "executable": "^4.1.0" - }, - "engines": { - "node": ">=4" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/bin-check/node_modules/cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.4.tgz", + "integrity": "sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==", + "cpu": [ + "ia32" + ], "license": "MIT", - "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/bin-check/node_modules/execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.4.tgz", + "integrity": "sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=4" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/bin-check/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.4.tgz", + "integrity": "sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==", + "cpu": [ + "x64" + ], "license": "MIT", - "engines": { - "node": ">=4" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/bin-check/node_modules/is-stream": { + "node_modules/@rtsao/scc": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "license": "MIT" }, - "node_modules/bin-check/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "license": "ISC", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "dev": true, + "license": "MIT" }, - "node_modules/bin-check/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "node_modules/@semantic-release/changelog": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-6.0.3.tgz", + "integrity": "sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==", + "dev": true, "license": "MIT", "dependencies": { - "path-key": "^2.0.0" + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "fs-extra": "^11.0.0", + "lodash": "^4.17.4" }, "engines": { - "node": ">=4" - } - }, - "node_modules/bin-check/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "license": "MIT", - "engines": { - "node": ">=4" + "node": ">=14.17" + }, + "peerDependencies": { + "semantic-release": ">=18.0.0" } }, - "node_modules/bin-check/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "node_modules/@semantic-release/commit-analyzer": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-13.0.1.tgz", + "integrity": "sha512-wdnBPHKkr9HhNhXOhZD5a2LNl91+hs8CC2vsAVYxtZH3y0dV3wKn+uZSN61rdJQZ8EGxzWB3inWocBHV9+u/CQ==", + "dev": true, "license": "MIT", "dependencies": { - "shebang-regex": "^1.0.0" + "conventional-changelog-angular": "^8.0.0", + "conventional-changelog-writer": "^8.0.0", + "conventional-commits-filter": "^5.0.0", + "conventional-commits-parser": "^6.0.0", + "debug": "^4.0.0", + "import-from-esm": "^2.0.0", + "lodash-es": "^4.17.21", + "micromatch": "^4.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=20.8.1" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" } }, - "node_modules/bin-check/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "node_modules/@semantic-release/error": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", + "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", + "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=14.17" } }, - "node_modules/bin-check/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "license": "ISC", + "node_modules/@semantic-release/git": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-10.0.1.tgz", + "integrity": "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==", + "dev": true, + "license": "MIT", "dependencies": { - "isexe": "^2.0.0" + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "execa": "^5.0.0", + "lodash": "^4.17.4", + "micromatch": "^4.0.0", + "p-reduce": "^2.0.0" }, - "bin": { - "which": "bin/which" + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "semantic-release": ">=18.0.0" } }, - "node_modules/bin-check/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "license": "ISC" - }, - "node_modules/bin-version": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-3.1.0.tgz", - "integrity": "sha512-Mkfm4iE1VFt4xd4vH+gx+0/71esbfus2LsnCGe8Pi4mndSPyT+NGES/Eg99jx8/lUGWfu3z2yuB/bt5UB+iVbQ==", + "node_modules/@semantic-release/github": { + "version": "12.0.8", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-12.0.8.tgz", + "integrity": "sha512-tej5AAgK5X9wHRoDmYhecMXEHEkFeGOY1XsEblKxu8pIQwahzf1STYyr7iPU6Lpbg6C5I3N2w/ocXrBo+L7jhw==", + "dev": true, "license": "MIT", "dependencies": { - "execa": "^1.0.0", - "find-versions": "^3.0.0" + "@octokit/core": "^7.0.0", + "@octokit/plugin-paginate-rest": "^14.0.0", + "@octokit/plugin-retry": "^8.0.0", + "@octokit/plugin-throttling": "^11.0.0", + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "debug": "^4.3.4", + "dir-glob": "^3.0.1", + "http-proxy-agent": "^9.0.0", + "https-proxy-agent": "^9.0.0", + "issue-parser": "^7.0.0", + "lodash-es": "^4.17.21", + "mime": "^4.0.0", + "p-filter": "^4.0.0", + "tinyglobby": "^0.2.14", + "undici": "^7.0.0", + "url-join": "^5.0.0" }, "engines": { - "node": ">=6" + "node": "^22.14.0 || >= 24.10.0" + }, + "peerDependencies": { + "semantic-release": ">=24.1.0" } }, - "node_modules/bin-version-check": { + "node_modules/@semantic-release/github/node_modules/@semantic-release/error": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-4.0.0.tgz", - "integrity": "sha512-sR631OrhC+1f8Cvs8WyVWOA33Y8tgwjETNPyyD/myRBXLkfS/vl74FmH/lFcRl9KY3zwGh7jFhvyk9vV3/3ilQ==", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "dev": true, "license": "MIT", - "dependencies": { - "bin-version": "^3.0.0", - "semver": "^5.6.0", - "semver-truncate": "^1.1.2" - }, "engines": { - "node": ">=6" - } - }, - "node_modules/bin-version-check/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "license": "ISC", - "bin": { - "semver": "bin/semver" + "node": ">=18" } }, - "node_modules/bin-version/node_modules/cross-spawn": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", - "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "node_modules/@semantic-release/github/node_modules/aggregate-error": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", + "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", + "dev": true, "license": "MIT", "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "clean-stack": "^5.2.0", + "indent-string": "^5.0.0" }, "engines": { - "node": ">=4.8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-version/node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "node_modules/@semantic-release/github/node_modules/clean-stack": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.3.0.tgz", + "integrity": "sha512-9ngPTOhYGQqNVSfeJkYXHmF7AGWp4/nN5D/QqNQs3Dvxd1Kk/WpjHfNujKHYUQ/5CoGyOyFNoWSPk5afzP0QVg==", + "dev": true, "license": "MIT", "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "escape-string-regexp": "5.0.0" }, "engines": { - "node": ">=6" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-version/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "node_modules/@semantic-release/github/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, "engines": { - "node": ">=6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-version/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "node_modules/@semantic-release/github/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-version/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "node_modules/@semantic-release/npm": { + "version": "13.1.5", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-13.1.5.tgz", + "integrity": "sha512-Hq5UxzoatN3LHiq2rTsWS54nCdqJHlsssGERCo8WlvdfFA9LoN0vO+OuKVSjtNapIc/S8C2LBj206wKLHg62mg==", + "dev": true, "license": "MIT", "dependencies": { - "path-key": "^2.0.0" + "@actions/core": "^3.0.0", + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "env-ci": "^11.2.0", + "execa": "^9.0.0", + "fs-extra": "^11.0.0", + "lodash-es": "^4.17.21", + "nerf-dart": "^1.0.0", + "normalize-url": "^9.0.0", + "npm": "^11.6.2", + "rc": "^1.2.8", + "read-pkg": "^10.0.0", + "registry-auth-token": "^5.0.0", + "semver": "^7.1.2", + "tempy": "^3.0.0" }, "engines": { - "node": ">=4" + "node": "^22.14.0 || >= 24.10.0" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" } }, - "node_modules/bin-version/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "node_modules/@semantic-release/npm/node_modules/@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "dev": true, "license": "MIT", "engines": { - "node": ">=4" - } - }, - "node_modules/bin-version/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "license": "ISC", - "bin": { - "semver": "bin/semver" + "node": ">=18" } }, - "node_modules/bin-version/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "node_modules/@semantic-release/npm/node_modules/aggregate-error": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", + "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", + "dev": true, "license": "MIT", "dependencies": { - "shebang-regex": "^1.0.0" + "clean-stack": "^5.2.0", + "indent-string": "^5.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/bin-version/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/bin-version/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" + "node": ">=18" }, - "bin": { - "which": "bin/which" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-wrapper": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bin-wrapper/-/bin-wrapper-4.1.0.tgz", - "integrity": "sha512-hfRmo7hWIXPkbpi0ZltboCMVrU+0ClXR/JgbCKKjlDjQf6igXa7OwdqNcFWQZPZTgiY7ZpzE3+LjjkLiTN2T7Q==", + "node_modules/@semantic-release/npm/node_modules/clean-stack": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.3.0.tgz", + "integrity": "sha512-9ngPTOhYGQqNVSfeJkYXHmF7AGWp4/nN5D/QqNQs3Dvxd1Kk/WpjHfNujKHYUQ/5CoGyOyFNoWSPk5afzP0QVg==", + "dev": true, "license": "MIT", "dependencies": { - "bin-check": "^4.1.0", - "bin-version-check": "^4.0.0", - "download": "^7.1.0", - "import-lazy": "^3.1.0", - "os-filter-obj": "^2.0.0", - "pify": "^4.0.1" + "escape-string-regexp": "5.0.0" }, "engines": { - "node": ">=6" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-wrapper/node_modules/@sindresorhus/is": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", - "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", + "node_modules/@semantic-release/npm/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-wrapper/node_modules/download": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz", - "integrity": "sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ==", + "node_modules/@semantic-release/npm/node_modules/execa": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", + "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", + "dev": true, "license": "MIT", "dependencies": { - "archive-type": "^4.0.0", - "caw": "^2.0.1", - "content-disposition": "^0.5.2", - "decompress": "^4.2.0", - "ext-name": "^5.0.0", - "file-type": "^8.1.0", - "filenamify": "^2.0.0", - "get-stream": "^3.0.0", - "got": "^8.3.1", - "make-dir": "^1.2.0", - "p-event": "^2.1.0", - "pify": "^3.0.0" + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.1.1" }, "engines": { - "node": ">=6" - } - }, - "node_modules/bin-wrapper/node_modules/download/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "license": "MIT", - "engines": { - "node": ">=4" + "node": "^18.19.0 || >=20.5.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/bin-wrapper/node_modules/file-type": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-8.1.0.tgz", - "integrity": "sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==", + "node_modules/@semantic-release/npm/node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "dev": true, "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, "engines": { - "node": ">=6" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-wrapper/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "node_modules/@semantic-release/npm/node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "dev": true, "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-wrapper/node_modules/got": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", - "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^0.7.0", - "cacheable-request": "^2.1.1", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "into-stream": "^3.1.0", - "is-retry-allowed": "^1.1.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "mimic-response": "^1.0.0", - "p-cancelable": "^0.4.0", - "p-timeout": "^2.0.1", - "pify": "^3.0.0", - "safe-buffer": "^5.1.1", - "timed-out": "^4.0.1", - "url-parse-lax": "^3.0.0", - "url-to-options": "^1.0.1" + "node_modules/@semantic-release/npm/node_modules/hosted-git-info": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.3.tgz", + "integrity": "sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^11.1.0" }, "engines": { - "node": ">=4" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/bin-wrapper/node_modules/got/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "license": "MIT", + "node_modules/@semantic-release/npm/node_modules/human-signals": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=4" + "node": ">=18.18.0" } }, - "node_modules/bin-wrapper/node_modules/into-stream": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", - "integrity": "sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==", + "node_modules/@semantic-release/npm/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, "license": "MIT", - "dependencies": { - "from2": "^2.1.1", - "p-is-promise": "^1.1.0" - }, "engines": { - "node": ">=4" - } - }, - "node_modules/bin-wrapper/node_modules/make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "license": "MIT", - "dependencies": { - "pify": "^3.0.0" + "node": ">=12" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-wrapper/node_modules/make-dir/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "node_modules/@semantic-release/npm/node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-wrapper/node_modules/p-cancelable": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", - "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", - "license": "MIT", + "node_modules/@semantic-release/npm/node_modules/lru-cache": { + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.0.tgz", + "integrity": "sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==", + "dev": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=4" + "node": "20 || >=22" } }, - "node_modules/bin-wrapper/node_modules/p-event": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz", - "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==", - "license": "MIT", + "node_modules/@semantic-release/npm/node_modules/normalize-package-data": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-8.0.0.tgz", + "integrity": "sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "p-timeout": "^2.0.1" + "hosted-git-info": "^9.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" }, "engines": { - "node": ">=6" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/bin-wrapper/node_modules/p-is-promise": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", - "integrity": "sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==", + "node_modules/@semantic-release/npm/node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "dev": true, "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-wrapper/node_modules/p-timeout": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", - "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "node_modules/@semantic-release/npm/node_modules/parse-json": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", + "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", + "dev": true, "license": "MIT", "dependencies": { - "p-finally": "^1.0.0" + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.1.0", + "type-fest": "^4.39.1" }, "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-wrapper/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "license": "MIT", + "node_modules/@semantic-release/npm/node_modules/parse-json/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=6" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-wrapper/node_modules/prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", + "node_modules/@semantic-release/npm/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-wrapper/node_modules/url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", + "node_modules/@semantic-release/npm/node_modules/read-pkg": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-10.1.0.tgz", + "integrity": "sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg==", + "dev": true, "license": "MIT", "dependencies": { - "prepend-http": "^2.0.0" + "@types/normalize-package-data": "^2.4.4", + "normalize-package-data": "^8.0.0", + "parse-json": "^8.3.0", + "type-fest": "^5.4.4", + "unicorn-magic": "^0.4.0" }, "engines": { - "node": ">=4" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/@semantic-release/npm/node_modules/read-pkg/node_modules/unicorn-magic": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", + "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", + "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bl": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", - "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", - "license": "MIT", - "dependencies": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" + "node_modules/@semantic-release/npm/node_modules/semver": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "license": "ISC" - }, - "node_modules/bottleneck": { - "version": "2.19.5", - "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", - "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "node_modules/@semantic-release/npm/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": "MIT" + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "node_modules/@semantic-release/npm/node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, "engines": { - "node": "18 || 20 || >=22" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", - "license": "MIT", + "node_modules/@semantic-release/npm/node_modules/type-fest": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.6.0.tgz", + "integrity": "sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", "dependencies": { - "fill-range": "^7.1.1" + "tagged-tag": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/breakpoint-sass": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/breakpoint-sass/-/breakpoint-sass-3.0.0.tgz", - "integrity": "sha512-qxJqSfTaOHI+RCGzvKWVRwwC2hMIaS0KV1b+asqWUFxdLv/yKNADF7AtT1uNnkt2VxSMZ2csM22CSc+Hez+EIg==", + "node_modules/@semantic-release/npm/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", - "peerDependencies": { - "sass": "^1.25" + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/browserslist": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", - "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", - "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" - } - ], + "node_modules/@semantic-release/release-notes-generator": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-14.1.1.tgz", + "integrity": "sha512-Pbd2e2XRMUD0OxehHpgd5/YghsE76cddkRHSoDvKLK+OCy4Ewxn49rWR631MEUU01lgwF/uyVXvbnVuu6+Z6VA==", + "dev": true, "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.10.12", - "caniuse-lite": "^1.0.30001782", - "electron-to-chromium": "^1.5.328", - "node-releases": "^2.0.36", - "update-browserslist-db": "^1.2.3" - }, - "bin": { - "browserslist": "cli.js" + "conventional-changelog-angular": "^8.0.0", + "conventional-changelog-writer": "^8.0.0", + "conventional-commits-filter": "^5.0.0", + "conventional-commits-parser": "^6.0.0", + "debug": "^4.0.0", + "import-from-esm": "^2.0.0", + "lodash-es": "^4.17.21", + "read-package-up": "^11.0.0" }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" + "node": ">=20.8.1" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" } }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "node_modules/@simple-git/args-pathspec": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@simple-git/args-pathspec/-/args-pathspec-1.0.3.tgz", + "integrity": "sha512-ngJMaHlsWDTfjyq9F3VIQ8b7NXbBLq5j9i5bJ6XLYtD6qlDXT7fdKY2KscWWUF8t18xx052Y/PUO1K1TRc9yKA==", + "license": "MIT" + }, + "node_modules/@simple-git/argv-parser": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@simple-git/argv-parser/-/argv-parser-1.1.1.tgz", + "integrity": "sha512-Q9lBcfQ+VQCpQqGJFHe5yooOS5hGdLFFbJ5R+R5aDsnkPCahtn1hSkMcORX65J2Z5lxSkD0lQorMsncuBQxYUw==", "license": "MIT", "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" + "@simple-git/args-pathspec": "^1.0.3" } }, - "node_modules/buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "node_modules/@simple-libs/child-process-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@simple-libs/child-process-utils/-/child-process-utils-1.0.2.tgz", + "integrity": "sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==", + "dev": true, "license": "MIT", "dependencies": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" + "@simple-libs/stream-utils": "^1.2.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://ko-fi.com/dangreen" } }, - "node_modules/buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "license": "MIT" - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "node_modules/@simple-libs/stream-utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@simple-libs/stream-utils/-/stream-utils-1.2.0.tgz", + "integrity": "sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==", + "dev": true, "license": "MIT", "engines": { - "node": "*" + "node": ">=18" + }, + "funding": { + "url": "https://ko-fi.com/dangreen" } }, - "node_modules/buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", - "license": "MIT" - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "node_modules/@sinclair/typebox": { + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "license": "MIT" }, - "node_modules/bundle-name": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", - "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, "license": "MIT", - "dependencies": { - "run-applescript": "^7.0.0" + "engines": { + "node": ">=10" }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "license": "MIT", "engines": { "node": ">=18" }, @@ -8716,2351 +5937,2967 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cacheable": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.4.tgz", - "integrity": "sha512-djgxybDbw9fL/ZWMI3+CE8ZilNxcwFkVtDc1gJ+IlOSSWkSMPQabhV/XCHTQ6pwwN6aivXPZ43omTooZiX06Ew==", - "license": "MIT", + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "license": "BSD-3-Clause", "dependencies": { - "@cacheable/memory": "^2.0.8", - "@cacheable/utils": "^2.4.0", - "hookified": "^1.15.0", - "keyv": "^5.6.0", - "qified": "^0.9.0" + "type-detect": "4.0.8" } }, - "node_modules/cacheable-request": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", - "integrity": "sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ==", - "license": "MIT", + "node_modules/@sinonjs/fake-timers": { + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz", + "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==", + "license": "BSD-3-Clause", "dependencies": { - "clone-response": "1.0.2", - "get-stream": "3.0.0", - "http-cache-semantics": "3.8.1", - "keyv": "3.0.0", - "lowercase-keys": "1.0.0", - "normalize-url": "2.0.1", - "responselike": "1.0.2" + "@sinonjs/commons": "^3.0.1" } }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "node_modules/@storybook/addon-a11y": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-10.4.1.tgz", + "integrity": "sha512-MGft/IXjJ20a9KbaSVG9bHTAAoanbucKrgEiJJRNqpim8DsXA01+XTdSk17LmiOCB203Rrq9mWgdQ6+79cc8iA==", "license": "MIT", - "engines": { - "node": ">=4" + "dependencies": { + "@storybook/global": "^5.0.0", + "axe-core": "^4.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.4.1" } }, - "node_modules/cacheable-request/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "node_modules/@storybook/addon-links": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-10.4.1.tgz", + "integrity": "sha512-h/5D23GwMuHA55sB7XDyhByF9psF7UFmaQOn72pjNAarew5eOpue5A+jXk3AKEYokHbvgQaoz+FrvWo9GEfSKQ==", "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "@storybook/global": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.4.1" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + } } }, - "node_modules/cacheable-request/node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", - "license": "MIT" - }, - "node_modules/cacheable-request/node_modules/keyv": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", - "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", + "node_modules/@storybook/addon-themes": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/addon-themes/-/addon-themes-10.4.1.tgz", + "integrity": "sha512-nxNskZwpgptCUWyci+jiM5IrKY6xSaTpv3xzgkL6NCU+5PyCxyp0Z6jE8NDvew9jolzOC9pBhGJAW26A/jbFqg==", "license": "MIT", "dependencies": { - "json-buffer": "3.0.0" + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.4.1" } }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A==", + "node_modules/@storybook/builder-vite": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.4.1.tgz", + "integrity": "sha512-/oyQrXoNOqN8SW5hNnYP+I1uvgFxKxWXj/EP6NXYzc5SQwImofgru+D2+6gDhL0+Q//+Hx05DJoQO2omvUJ8bQ==", "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "@storybook/csf-plugin": "10.4.1", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.4.1", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/cacheable-request/node_modules/normalize-url": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", - "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "node_modules/@storybook/csf-plugin": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.4.1.tgz", + "integrity": "sha512-WdPepGBxDGOUDjYd8KxMtcf+us/2PAcnBczl77XtrnxxHNs0jWesxKkiJ9yiuGrge4BPhDeAj6rxjbBoaHxLBA==", "license": "MIT", "dependencies": { - "prepend-http": "^2.0.0", - "query-string": "^5.0.1", - "sort-keys": "^2.0.0" + "unplugin": "^2.3.5" }, - "engines": { - "node": ">=4" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "esbuild": "*", + "rollup": "*", + "storybook": "^10.4.1", + "vite": "*", + "webpack": "*" + }, + "peerDependenciesMeta": { + "esbuild": { + "optional": true + }, + "rollup": { + "optional": true + }, + "vite": { + "optional": true + }, + "webpack": { + "optional": true + } } }, - "node_modules/cacheable-request/node_modules/prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", + "node_modules/@storybook/global": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz", + "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==", + "license": "MIT" + }, + "node_modules/@storybook/icons": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-2.0.2.tgz", + "integrity": "sha512-KZBCpXsshAIjczYNXR/rlxEtCUX/eAbpFNwKi8bcOomrLA4t/SyPz5RF+lVPO2oZBUE4sAkt43mfJUevQDSEEw==", "license": "MIT", - "engines": { - "node": ">=4" + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, - "node_modules/cacheable-request/node_modules/sort-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==", + "node_modules/@storybook/react": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.4.1.tgz", + "integrity": "sha512-WuYz4NaUk4gmFAMliSpCbV8w6jP5OY9juBfw1huwzu2S/k5FhnVXwmrUaL0fmf3Bq/7NgkzmBBbZr6I6LuHayQ==", "license": "MIT", "dependencies": { - "is-plain-obj": "^1.0.0" + "@storybook/global": "^5.0.0", + "@storybook/react-dom-shim": "10.4.1", + "react-docgen": "^8.0.2", + "react-docgen-typescript": "^2.2.2" }, - "engines": { - "node": ">=4" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.4.1", + "typescript": ">= 4.9.x" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "typescript": { + "optional": true + } } }, - "node_modules/cacheable/node_modules/keyv": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", - "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "node_modules/@storybook/react-dom-shim": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.4.1.tgz", + "integrity": "sha512-6QFqfDNH4DMrt7yHKRfpqRopsVUc/Az+sXIdJ39IetYnHUxL3nW4NVaPc6uy/8Qi8urzUyEXL/nn7cpSIP2aPQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.4.1" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@storybook/react-vite": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-10.4.1.tgz", + "integrity": "sha512-zY6OzaXvXqBIUyc5ySE55/LAPQiF+o9ZyhQI978WMu4mY/fL7FpQ+ZVHRUCCgz/wTXtqE9jJwd/N10HI1kD0/Q==", "license": "MIT", "dependencies": { - "@keyv/serialize": "^1.1.1" + "@joshwooding/vite-plugin-react-docgen-typescript": "^0.7.0", + "@rollup/pluginutils": "^5.0.2", + "@storybook/builder-vite": "10.4.1", + "@storybook/react": "10.4.1", + "empathic": "^2.0.0", + "magic-string": "^0.30.0", + "react-docgen": "^8.0.0", + "resolve": "^1.22.8", + "tsconfig-paths": "^4.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.4.1", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/call-bind": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", - "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "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==", "license": "MIT", + "peer": true, "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "get-intrinsic": "^1.3.0", - "set-function-length": "^1.2.2" + "@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": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18" } }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "node_modules/@testing-library/dom/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==", "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, + "peer": true, "engines": { - "node": ">= 0.4" + "node": ">=8" } }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "node_modules/@testing-library/dom/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==", "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, + "peer": true, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/@testing-library/dom/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==", "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, "engines": { - "node": ">=6" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", "license": "MIT", "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "license": "MIT", + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, "engines": { - "node": ">=6" + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001787", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001787.tgz", - "integrity": "sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg==", - "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/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "license": "MIT" }, - "node_modules/case-sensitive-paths-webpack-plugin": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", - "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", + "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==", "license": "MIT", "engines": { - "node": ">=4" - } - }, - "node_modules/caw": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz", - "integrity": "sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==", - "license": "MIT", - "dependencies": { - "get-proxy": "^2.0.0", - "isurl": "^1.0.0-alpha5", - "tunnel-agent": "^0.6.0", - "url-to-options": "^1.0.1" + "node": ">=12", + "npm": ">=6" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" } }, - "node_modules/chai": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", - "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "node_modules/@tokenizer/inflate": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz", + "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", "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" + "debug": "^4.4.3", + "token-types": "^6.1.1" }, "engines": { "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "license": "MIT" + }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "license": "MIT" + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", "license": "MIT", + "optional": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "tslib": "^2.4.0" } }, - "node_modules/change-case": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-3.1.0.tgz", - "integrity": "sha512-2AZp7uJZbYEzRPsFoa+ijKdvp9zsrnnt6+yFokfwEpeJm0xuJDVoxiRCAaTzyJND8GJkofo2IcKWaUZ/OECVzw==", - "license": "MIT", - "dependencies": { - "camel-case": "^3.0.0", - "constant-case": "^2.0.0", - "dot-case": "^2.1.0", - "header-case": "^1.0.0", - "is-lower-case": "^1.1.0", - "is-upper-case": "^1.1.0", - "lower-case": "^1.1.1", - "lower-case-first": "^1.0.0", - "no-case": "^2.3.2", - "param-case": "^2.1.0", - "pascal-case": "^2.0.0", - "path-case": "^2.1.0", - "sentence-case": "^2.1.0", - "snake-case": "^2.1.0", - "swap-case": "^1.1.0", - "title-case": "^2.1.0", - "upper-case": "^1.1.1", - "upper-case-first": "^1.1.0" - } - }, - "node_modules/change-case/node_modules/camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", + "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==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "license": "MIT", "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" } }, - "node_modules/change-case/node_modules/param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", "license": "MIT", "dependencies": { - "no-case": "^2.2.0" + "@babel/types": "^7.0.0" } }, - "node_modules/change-case/node_modules/pascal-case": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz", - "integrity": "sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==", + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "license": "MIT", "dependencies": { - "camel-case": "^3.0.0", - "upper-case-first": "^1.1.0" + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "node_modules/change-file-extension": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/change-file-extension/-/change-file-extension-0.1.1.tgz", - "integrity": "sha512-lB0j9teu8JtDPDHRfU8pNH33w4wMu5bOaKoT4PxH+AKugBrIfpiJMTTKIm0TErNeJPkeQEgvH31YpccTwOKPRg==", + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "@babel/types": "^7.28.2" } }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "license": "MIT", - "engines": { - "node": ">=10" + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" } }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "license": "MIT" }, - "node_modules/check-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", - "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", - "license": "MIT", - "engines": { - "node": ">= 16" - } + "node_modules/@types/doctrine": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz", + "integrity": "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==", + "license": "MIT" }, - "node_modules/check-types": { - "version": "11.2.3", - "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz", - "integrity": "sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==", + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", "license": "MIT" }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "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" + "@types/istanbul-lib-coverage": "*" } }, - "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==", - "license": "ISC", + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "license": "MIT", "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" + "@types/istanbul-lib-report": "*" } }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "node_modules/@types/jsdom": { + "version": "21.1.7", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz", + "integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==", "license": "MIT", - "engines": { - "node": ">=6.0" + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" } }, - "node_modules/chromium-bidi": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-14.0.0.tgz", - "integrity": "sha512-9gYlLtS6tStdRWzrtXaTMnqcM4dudNegMXJxkR0I/CXObHalYeYcAMPrL19eroNZHtJ8DQmu1E+ZNOYu/IXMXw==", - "license": "Apache-2.0", + "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==", + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz", + "integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==", + "license": "MIT", "dependencies": { - "mitt": "^3.0.1", - "zod": "^3.24.1" - }, - "peerDependencies": { - "devtools-protocol": "*" + "undici-types": ">=7.24.0 <7.24.7" } }, - "node_modules/ci-info": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", - "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/progress": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/progress/-/progress-2.0.7.tgz", + "integrity": "sha512-iadjw02vte8qWx7U0YM++EybBha2CQLPGu9iJ97whVgJUT5Zq9MjAPYUnbfRI2Kpehimf1QjFJYxD0t8nqzu5w==", "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "@types/node": "*" } }, - "node_modules/cjs-module-lexer": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", - "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "node_modules/@types/resolve": { + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz", + "integrity": "sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==", "license": "MIT" }, - "node_modules/clean-css": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", - "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "license": "MIT" + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", "license": "MIT", "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" + "@types/yargs-parser": "*" } }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "license": "MIT" + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "license": "MIT", - "engines": { - "node": ">=6" + "optional": true, + "dependencies": { + "@types/node": "*" } }, - "node_modules/clean-webpack-plugin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-4.0.0.tgz", - "integrity": "sha512-WuWE1nyTNAyW5T7oNyys2EN0cfP2fdRxhxnIQWiAp0bMabPdHhoGxM8A6YL2GhqwgrPnnaemVE7nv5XJ2Fhh2w==", + "node_modules/@typescript-eslint/project-service": { + "version": "8.59.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.4.tgz", + "integrity": "sha512-Ly00Vu4oAacfDeHp2Zg85ioNG6l8HG+tN1D7J+xTHSxu9y0awYKJ2zH1rFBn8ZSfuGK+7FxK3Cgl3uAz0aZZLg==", "license": "MIT", "dependencies": { - "del": "^4.1.1" + "@typescript-eslint/tsconfig-utils": "^8.59.4", + "@typescript-eslint/types": "^8.59.4", + "debug": "^4.4.3" }, "engines": { - "node": ">=10.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "webpack": ">=4.0.0 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.59.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.4.tgz", + "integrity": "sha512-mUeR/3H1WrTAddJrwut8OoPjfauaztMQmRwV5fQTUyNVJCLiUXXe4lGEyYIL2oFDpP7UtgbGJXCt72wT0z2S3Q==", "license": "MIT", "dependencies": { - "restore-cursor": "^3.1.0" + "@typescript-eslint/types": "8.59.4", + "@typescript-eslint/visitor-keys": "8.59.4" }, "engines": { - "node": ">=8" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/cli-highlight": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", - "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", - "dev": true, - "license": "ISC", - "dependencies": { - "chalk": "^4.0.0", - "highlight.js": "^10.7.1", - "mz": "^2.4.0", - "parse5": "^5.1.1", - "parse5-htmlparser2-tree-adapter": "^6.0.0", - "yargs": "^16.0.0" + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.59.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.4.tgz", + "integrity": "sha512-DLCpnKgD4alVxTBSKulK+gU1KCqOgUXfDRDXh2mZgzokQKa/70ax93I2uVO3m/LLvIAtWZIFoiifudmIqAxpMA==", + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "bin": { - "highlight": "bin/highlight" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, - "engines": { - "node": ">=8.0.0", - "npm": ">=5.0.0" - } - }, - "node_modules/cli-highlight/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" + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/cli-highlight/node_modules/parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "dev": true, - "license": "MIT" - }, - "node_modules/cli-highlight/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, + "node_modules/@typescript-eslint/types": { + "version": "8.59.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.4.tgz", + "integrity": "sha512-F1o7WJcCq+bc8dwcO/YsSEOudAH8RDtaOhM6wcAQhcUsFhnWQl81JKy48q1hoxAU0qrzM89+31GYh1515Zde3Q==", "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/cli-highlight/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, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.59.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.4.tgz", + "integrity": "sha512-F+RuOmcDXo4+TPdfd/TCLS3m2nw8gE9XXyZLrA3JBfaA5tz9TtdkyD3YJFmPxulyc2cKbEok/CvFE3MgSLWnag==", "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" + "@typescript-eslint/project-service": "8.59.4", + "@typescript-eslint/tsconfig-utils": "8.59.4", + "@typescript-eslint/types": "8.59.4", + "@typescript-eslint/visitor-keys": "8.59.4", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/cli-highlight/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", + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", "engines": { - "node": ">=10" + "node": "18 || 20 || >=22" } }, - "node_modules/cli-table3": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", - "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", - "dev": true, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "license": "MIT", "dependencies": { - "string-width": "^4.2.0" + "balanced-match": "^4.0.2" }, "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" + "node": "18 || 20 || >=22" } }, - "node_modules/cli-truncate": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", - "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", - "dev": true, - "license": "MIT", + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", "dependencies": { - "slice-ansi": "^8.0.0", - "string-width": "^8.2.0" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=20" + "node": "18 || 20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/cli-truncate/node_modules/string-width": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.0.tgz", - "integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==", - "dev": true, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.59.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.4.tgz", + "integrity": "sha512-cYXeNAUsG4lJo5dbc1FcKm+JwIWrj1/UpTORsC6tGMjEZ81DYcvIr9/ueikhMa/Y/gDQYGp+YX9/xQrXje5BJw==", "license": "MIT", "dependencies": { - "get-east-asian-width": "^1.5.0", - "strip-ansi": "^7.1.2" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.59.4", + "@typescript-eslint/types": "8.59.4", + "@typescript-eslint/typescript-estree": "8.59.4" }, "engines": { - "node": ">=20" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/cli-truncate/node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "dev": true, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.59.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.4.tgz", + "integrity": "sha512-U3gxVaDVnuZKhSspW/MzMxE1kq7zOdc072FcSNoqA1I9p8HyKbBFfEHoWckBAMgNMph4MamwS5iTVzFmrnt8TQ==", "license": "MIT", "dependencies": { - "ansi-regex": "^6.2.2" + "@typescript-eslint/types": "8.59.4", + "eslint-visitor-keys": "^5.0.0" }, "engines": { - "node": ">=12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true, - "license": "ISC", + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "license": "Apache-2.0", "engines": { - "node": ">= 10" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, - "engines": { - "node": ">=12" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "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==", + "node_modules/@ungap/structured-clone": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.1.tgz", + "integrity": "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==", + "license": "ISC" + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz", + "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz", + "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz", + "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz", + "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz", + "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz", + "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz", + "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz", + "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz", + "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz", + "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz", + "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz", + "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz", + "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz", + "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz", + "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz", + "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz", + "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-openharmony-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz", + "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz", + "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==", + "cpu": [ + "wasm32" + ], "license": "MIT", + "optional": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=14.0.0" } }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", "license": "MIT", + "optional": true, "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" } }, - "node_modules/clone-deep/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", "license": "MIT", + "optional": true, "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "tslib": "^2.4.0" } }, - "node_modules/clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==", + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", + "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "mimic-response": "^1.0.0" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz", + "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==", + "cpu": [ + "ia32" + ], "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/collect-v8-coverage": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", - "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", - "license": "MIT" + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz", + "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "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==", + "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==", "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" }, - "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==", - "license": "MIT" - }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "license": "MIT" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "license": "MIT" - }, - "node_modules/colorjs.io": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.5.2.tgz", - "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==", - "license": "MIT" - }, - "node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "license": "MIT", - "engines": { - "node": ">=18" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", - "dev": 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==", "license": "MIT", "dependencies": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/component-emitter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-2.0.0.tgz", - "integrity": "sha512-4m5s3Me2xxlVKG9PkZpQqHQR7bgpnN7joDMJ4yvVkVXngjoITG76IaZmzmywSeRTeTpc6N6r3H3+KyUurV8OYw==", + "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==", "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "tinyspy": "^4.0.3" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/vitest" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/concurrently": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz", - "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==", + "node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", "license": "MIT", "dependencies": { - "chalk": "4.1.2", - "rxjs": "7.8.2", - "shell-quote": "1.8.3", - "supports-color": "8.1.1", - "tree-kill": "1.2.2", - "yargs": "17.7.2" - }, - "bin": { - "conc": "dist/bin/concurrently.js", - "concurrently": "dist/bin/concurrently.js" - }, - "engines": { - "node": ">=18" + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" }, "funding": { - "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + "url": "https://opencollective.com/vitest" } }, - "node_modules/concurrently/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", + "node_modules/@vituum/vite-plugin-twig": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@vituum/vite-plugin-twig/-/vite-plugin-twig-1.1.0.tgz", + "integrity": "sha512-5bUwGe0x0eUsxZ9rX3vHH8rV1ftBDgcyCKFlmAhaxNp4Adcmeybuon2cXBbRKwg0K4l6aiCcYp8+I3eVrZ/XGA==", "dependencies": { - "has-flag": "^4.0.0" + "lodash": "^4.17", + "twig": "^1.17", + "vituum": "^1.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": "^18.0.0 || >=20.0.0" } }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "license": "MIT", + "node_modules/@vituum/vite-plugin-twig/node_modules/twig": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/twig/-/twig-1.17.1.tgz", + "integrity": "sha512-atxccyr/BHtb1gPMA7Lvki0OuU17XBqHsNH9lzDHt9Rr1293EVZOosSZabEXz/DPVikIW8ZDqSkEddwyJnQN2w==", + "license": "BSD-2-Clause", "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" + "@babel/runtime": "^7.8.4", + "locutus": "^2.0.11", + "minimatch": "3.0.x", + "walk": "2.3.x" + }, + "bin": { + "twigjs": "bin/twigjs" + }, + "engines": { + "node": ">=10" } }, - "node_modules/config-chain/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "license": "ISC" - }, - "node_modules/consola": { - "version": "2.15.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", - "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==", + "node_modules/@webcontainer/env": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@webcontainer/env/-/env-1.1.1.tgz", + "integrity": "sha512-6aN99yL695Hi9SuIk1oC88l9o0gmxL1nGWWQ/kNy81HigJ0FoaoTXpytCj6ItzgyCEwA9kF1wixsTuv5cjsgng==", "license": "MIT" }, - "node_modules/constant-case": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-2.0.0.tgz", - "integrity": "sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ==", + "node_modules/@xmldom/xmldom": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.10.tgz", + "integrity": "sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==", "license": "MIT", - "dependencies": { - "snake-case": "^2.1.0", - "upper-case": "^1.1.1" + "engines": { + "node": ">=14.6" } }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">= 0.6" + "node": ">=0.4.0" } }, - "node_modules/conventional-changelog-angular": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.3.1.tgz", - "integrity": "sha512-6gfI3otXK5Ph5DfCOI1dblr+kN3FAm5a97hYoQkqNZxOaYa5WKfXH+AnpsmS+iUH2mgVC2Cg2Qw9m5OKcmNrIg==", + "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==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", + "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", "dev": true, - "license": "ISC", - "dependencies": { - "compare-func": "^2.0.0" - }, + "license": "MIT", "engines": { - "node": ">=18" + "node": ">= 20" } }, - "node_modules/conventional-changelog-conventionalcommits": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-9.3.1.tgz", - "integrity": "sha512-dTYtpIacRpcZgrvBYvBfArMmK2xvIpv2TaxM0/ZI5CBtNUzvF2x0t15HsbRABWprS6UPmvj+PzHVjSx4qAVKyw==", + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "compare-func": "^2.0.0" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" }, "engines": { - "node": ">=18" + "node": ">=8" } }, - "node_modules/conventional-changelog-writer": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-8.4.0.tgz", - "integrity": "sha512-HHBFkk1EECxxmCi4CTu091iuDpQv5/OavuCUAuZmrkWpmYfyD816nom1CvtfXJ/uYfAAjavgHvXHX291tSLK8g==", - "dev": true, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "license": "MIT", "dependencies": { - "@simple-libs/stream-utils": "^1.2.0", - "conventional-commits-filter": "^5.0.0", - "handlebars": "^4.7.7", - "meow": "^13.0.0", - "semver": "^7.5.2" - }, - "bin": { - "conventional-changelog-writer": "dist/cli/index.js" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, - "engines": { - "node": ">=18" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/conventional-changelog-writer/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" }, - "engines": { - "node": ">=10" + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, - "node_modules/conventional-commits-filter": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-5.0.0.tgz", - "integrity": "sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==", - "dev": true, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "license": "MIT", "engines": { - "node": ">=18" + "node": ">=6" } }, - "node_modules/conventional-commits-parser": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.4.0.tgz", - "integrity": "sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw==", - "dev": true, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "license": "MIT", "dependencies": { - "@simple-libs/stream-utils": "^1.2.0", - "meow": "^13.0.0" - }, - "bin": { - "conventional-commits-parser": "dist/cli/index.js" + "type-fest": "^0.21.3" }, "engines": { - "node": ">=18" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/convert-hrtime": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-5.0.0.tgz", - "integrity": "sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==", + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "license": "MIT", "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "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==", - "license": "MIT" - }, - "node_modules/copy-webpack-plugin": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-14.0.0.tgz", - "integrity": "sha512-3JLW90aBGeaTLpM7mYQKpnVdgsUZRExY55giiZgLuX/xTQRUs1dOCwbBnWnvY6Q6rfZoXMNwzOQJCSZPppfqXA==", + "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==", "license": "MIT", "dependencies": { - "glob-parent": "^6.0.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.2.0", - "serialize-javascript": "^7.0.3", - "tinyglobby": "^0.2.12" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 20.9.0" + "node": ">=8" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/core-js": { - "version": "3.49.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz", - "integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==", - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" }, - "node_modules/core-js-compat": { - "version": "3.49.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", - "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", - "license": "MIT", + "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==", + "license": "ISC", "dependencies": { - "browserslist": "^4.28.1" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" + "engines": { + "node": ">= 8" } }, - "node_modules/core-js-pure": { - "version": "3.49.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.49.0.tgz", - "integrity": "sha512-XM4RFka59xATyJv/cS3O3Kml72hQXUeGRuuTmMYFxwzc9/7C8OYTaIR/Ji+Yt8DXzsFLNhat15cE/JP15HrCgw==", - "hasInstallScript": true, + "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==", + "license": "Python-2.0" + }, + "node_modules/argv-formatter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", + "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", + "dev": true, + "license": "MIT" + }, + "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==", + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true, "license": "MIT" }, - "node_modules/cosmiconfig": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", - "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", "license": "MIT", "dependencies": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" }, "engines": { - "node": ">=14" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cosmiconfig-typescript-loader": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.3.0.tgz", - "integrity": "sha512-Akr82WH1Wfqatyiqpj8HDkO2o2KmJRu1FhKfSNJP3K4IdXwHfEyL7MOb62i1AGQVLtIQM+iCE9CGOtrfhR+mmA==", - "dev": true, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", "license": "MIT", "dependencies": { - "jiti": "2.6.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" }, "engines": { - "node": ">=v18" + "node": ">= 0.4" }, - "peerDependencies": { - "@types/node": "*", - "cosmiconfig": ">=9", - "typescript": ">=5" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "license": "MIT", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { - "node": ">= 8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/crypto-random-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "license": "MIT", "dependencies": { - "type-fest": "^1.0.1" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/crypto-random-string/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "license": "(MIT OR CC0-1.0)", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/css-functions-list": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.3.3.tgz", - "integrity": "sha512-8HFEBPKhOpJPEPu70wJJetjKta86Gw9+CCyCnB3sui2qQfOvRyqBy4IKLKKAwdMpWb2lHXWk9Wb4Z6AmaUT1Pg==", + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "license": "MIT", "engines": { "node": ">=12" } }, - "node_modules/css-loader": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.4.tgz", - "integrity": "sha512-vv3J9tlOl04WjiMvHQI/9tmIrCxVrj6PFbHemBB1iihpeRbi/I4h033eoFIhwxBBqLhI0KYFS7yvynBFhIZfTw==", + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", "license": "MIT", "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.40", - "postcss-modules-extract-imports": "^3.1.0", - "postcss-modules-local-by-default": "^4.0.5", - "postcss-modules-scope": "^3.2.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.6.3" + "tslib": "^2.0.1" }, "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || ^1.0.0 || ^2.0.0-0", - "webpack": "^5.27.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } + "node": ">=4" } }, - "node_modules/css-loader/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/css-node-extract": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-node-extract/-/css-node-extract-2.1.3.tgz", - "integrity": "sha512-E7CzbC0I4uAs2dI8mPCVe+K37xuja5kjIugOotpwICFL7vzhmFMAPHvS/MF9gFrmv8DDUANsxrgyT/I3OLukcw==", + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", "license": "MIT", - "dependencies": { - "change-case": "^3.0.1", - "postcss": "^6.0.14" + "engines": { + "node": ">= 0.4" } }, - "node_modules/css-node-extract/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/autoprefixer": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.0.tgz", + "integrity": "sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "browserslist": "^4.28.2", + "caniuse-lite": "^1.0.30001787", + "fraction.js": "^5.3.4", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" }, "engines": { - "node": ">=4" + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, - "node_modules/css-node-extract/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.11.4", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.4.tgz", + "integrity": "sha512-KunSNx+TVpkAw/6ULfhnx+HWRecjqZGTOyquAoWHYLRSdK1tB5Ihce1ZW+UY3fj33bYAFWPu7W/GRSmmrCGuxA==", + "license": "MPL-2.0", "engines": { "node": ">=4" } }, - "node_modules/css-node-extract/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" + "node_modules/b4a": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.1.tgz", + "integrity": "sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==", + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } } }, - "node_modules/css-node-extract/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "node_modules/babel-helper-evaluate-path": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.5.0.tgz", + "integrity": "sha512-mUh0UhS607bGh5wUMAQfOpt2JX2ThXMtppHRdRU1kL7ZLRWIXxoV2UIV1r2cAeeNeU1M5SB5/RSUgUxrK8yOkA==", "license": "MIT" }, - "node_modules/css-node-extract/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } + "node_modules/babel-helper-flip-expressions": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.4.3.tgz", + "integrity": "sha512-rSrkRW4YQ2ETCWww9gbsWk4N0x1BOtln349Tk0dlCS90oT68WMLyGR7WvaMp3eAnsVrCqdUtC19lo1avyGPejA==", + "license": "MIT" }, - "node_modules/css-node-extract/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/babel-helper-is-nodes-equiv": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz", + "integrity": "sha512-ri/nsMFVRqXn7IyT5qW4/hIAGQxuYUFHa3qsxmPtbk6spZQcYlyDogfVpNm2XYOslH/ULS4VEJGUqQX5u7ACQw==", + "license": "MIT" + }, + "node_modules/babel-helper-is-void-0": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-is-void-0/-/babel-helper-is-void-0-0.4.3.tgz", + "integrity": "sha512-07rBV0xPRM3TM5NVJEOQEkECX3qnHDjaIbFvWYPv+T1ajpUiVLiqTfC+MmiZxY5KOL/Ec08vJdJD9kZiP9UkUg==", + "license": "MIT" + }, + "node_modules/babel-helper-mark-eval-scopes": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.4.3.tgz", + "integrity": "sha512-+d/mXPP33bhgHkdVOiPkmYoeXJ+rXRWi7OdhwpyseIqOS8CmzHQXHUp/+/Qr8baXsT0kjGpMHHofHs6C3cskdA==", + "license": "MIT" + }, + "node_modules/babel-helper-remove-or-void": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.4.3.tgz", + "integrity": "sha512-eYNceYtcGKpifHDir62gHJadVXdg9fAhuZEXiRQnJJ4Yi4oUTpqpNY//1pM4nVyjjDMPYaC2xSf0I+9IqVzwdA==", + "license": "MIT" + }, + "node_modules/babel-helper-to-multiple-sequence-expressions": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.5.0.tgz", + "integrity": "sha512-m2CvfDW4+1qfDdsrtf4dwOslQC3yhbgyBFptncp4wvtdrDHqueW7slsYv4gArie056phvQFhT2nRcGS4bnm6mA==", + "license": "MIT" + }, + "node_modules/babel-jest": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.4.1.tgz", + "integrity": "sha512-fATAbM8piYxkiXQp3RBXmZHxZVNJZAVXXfyeyCN2Tida3+qJ8ea9UxhiJ2y4fLO90ZImKt6k9FlcH2+rLkJGhw==", "license": "MIT", + "dependencies": { + "@jest/transform": "30.4.1", + "@types/babel__core": "^7.20.5", + "babel-plugin-istanbul": "^7.0.1", + "babel-preset-jest": "30.4.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "slash": "^3.0.0" + }, "engines": { - "node": ">=4" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0 || ^8.0.0-0" } }, - "node_modules/css-node-extract/node_modules/postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "license": "MIT", + "node_modules/babel-plugin-istanbul": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", + "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", + "license": "BSD-3-Clause", + "workspaces": [ + "test/babel-8" + ], "dependencies": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-instrument": "^6.0.2", + "test-exclude": "^6.0.0" }, "engines": { - "node": ">=4.0.0" + "node": ">=12" } }, - "node_modules/css-node-extract/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/babel-plugin-jest-hoist": { + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.4.0.tgz", + "integrity": "sha512-9EdtWM/sSfXLOGLwSn+GS6pIXyBnL07/8gyJlwFXjWy4DxMOyItqyUT29d4lQiS380EZwYlX7/At4PgBS+m2aA==", "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@types/babel__core": "^7.20.5" }, "engines": { - "node": ">=4" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "license": "BSD-2-Clause", + "node_modules/babel-plugin-minify-builtins": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.5.0.tgz", + "integrity": "sha512-wpqbN7Ov5hsNwGdzuzvFcjgRlzbIeVv1gMIlICbPj0xkexnfoIDe7q+AZHMkQmAE/F9R5jkrB6TLfTegImlXag==", + "license": "MIT" + }, + "node_modules/babel-plugin-minify-constant-folding": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.5.0.tgz", + "integrity": "sha512-Vj97CTn/lE9hR1D+jKUeHfNy+m1baNiJ1wJvoGyOBUx7F7kJqDZxr9nCHjO/Ad+irbR3HzR6jABpSSA29QsrXQ==", + "license": "MIT", "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" + "babel-helper-evaluate-path": "^0.5.0" } }, - "node_modules/css-selector-extract": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/css-selector-extract/-/css-selector-extract-3.3.6.tgz", - "integrity": "sha512-bBI8ZJKKyR9iHvxXb4t3E6WTMkis94eINopVg7y2FmmMjLXUVduD7mPEcADi4i9FX4wOypFMFpySX+0keuefxg==", + "node_modules/babel-plugin-minify-dead-code-elimination": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.5.2.tgz", + "integrity": "sha512-krq9Lwi0QIzyAlcNBXTL4usqUvevB4BzktdEsb8srcXC1AaYqRJiAQw6vdKdJSaXbz6snBvziGr6ch/aoRCfpA==", "license": "MIT", "dependencies": { - "postcss": "^6.0.14" + "babel-helper-evaluate-path": "^0.5.0", + "babel-helper-mark-eval-scopes": "^0.4.3", + "babel-helper-remove-or-void": "^0.4.3", + "lodash": "^4.17.11" } }, - "node_modules/css-selector-extract/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/babel-plugin-minify-flip-comparisons": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.4.3.tgz", + "integrity": "sha512-8hNwgLVeJzpeLVOVArag2DfTkbKodzOHU7+gAZ8mGBFGPQHK6uXVpg3jh5I/F6gfi5Q5usWU2OKcstn1YbAV7A==", "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" + "babel-helper-is-void-0": "^0.4.3" } }, - "node_modules/css-selector-extract/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/babel-plugin-minify-guarded-expressions": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.4.4.tgz", + "integrity": "sha512-RMv0tM72YuPPfLT9QLr3ix9nwUIq+sHT6z8Iu3sLbqldzC1Dls8DPCywzUIzkTx9Zh1hWX4q/m9BPoPed9GOfA==", "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" + "babel-helper-evaluate-path": "^0.5.0", + "babel-helper-flip-expressions": "^0.4.3" } }, - "node_modules/css-selector-extract/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/babel-plugin-minify-infinity": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.4.3.tgz", + "integrity": "sha512-X0ictxCk8y+NvIf+bZ1HJPbVZKMlPku3lgYxPmIp62Dp8wdtbMLSekczty3MzvUOlrk5xzWYpBpQprXUjDRyMA==", + "license": "MIT" + }, + "node_modules/babel-plugin-minify-mangle-names": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.5.1.tgz", + "integrity": "sha512-8KMichAOae2FHlipjNDTo2wz97MdEb2Q0jrn4NIRXzHH7SJ3c5TaNNBkeTHbk9WUsMnqpNUx949ugM9NFWewzw==", "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "babel-helper-mark-eval-scopes": "^0.4.3" } }, - "node_modules/css-selector-extract/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "node_modules/babel-plugin-minify-numeric-literals": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.4.3.tgz", + "integrity": "sha512-5D54hvs9YVuCknfWywq0eaYDt7qYxlNwCqW9Ipm/kYeS9gYhJd0Rr/Pm2WhHKJ8DC6aIlDdqSBODSthabLSX3A==", "license": "MIT" }, - "node_modules/css-selector-extract/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/babel-plugin-minify-replace": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.5.0.tgz", + "integrity": "sha512-aXZiaqWDNUbyNNNpWs/8NyST+oU7QTpK7J9zFEFSA0eOmtUNMU3fczlTTTlnCxHmq/jYNFEmkkSG3DDBtW3Y4Q==", + "license": "MIT" + }, + "node_modules/babel-plugin-minify-simplify": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.5.1.tgz", + "integrity": "sha512-OSYDSnoCxP2cYDMk9gxNAed6uJDiDz65zgL6h8d3tm8qXIagWGMLWhqysT6DY3Vs7Fgq7YUDcjOomhVUb+xX6A==", "license": "MIT", - "engines": { - "node": ">=0.8.0" + "dependencies": { + "babel-helper-evaluate-path": "^0.5.0", + "babel-helper-flip-expressions": "^0.4.3", + "babel-helper-is-nodes-equiv": "^0.0.1", + "babel-helper-to-multiple-sequence-expressions": "^0.5.0" } }, - "node_modules/css-selector-extract/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/babel-plugin-minify-type-constructors": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.4.3.tgz", + "integrity": "sha512-4ADB0irJ/6BeXWHubjCJmrPbzhxDgjphBMjIjxCc25n4NGJ00NsYqwYt+F/OvE9RXx8KaSW7cJvp+iZX436tnQ==", "license": "MIT", - "engines": { - "node": ">=4" + "dependencies": { + "babel-helper-is-void-0": "^0.4.3" } }, - "node_modules/css-selector-extract/node_modules/postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", + "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", "license": "MIT", "dependencies": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.8", + "semver": "^6.3.1" }, - "engines": { - "node": ">=4.0.0" + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/css-selector-extract/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.2.tgz", + "integrity": "sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==", "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@babel/helper-define-polyfill-provider": "^0.6.8", + "core-js-compat": "^3.48.0" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/css-tree": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", - "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", + "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", "license": "MIT", "dependencies": { - "mdn-data": "2.27.1", - "source-map-js": "^1.2.1" + "@babel/helper-define-polyfill-provider": "^0.6.8" }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/css-what": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", - "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } + "node_modules/babel-plugin-transform-inline-consecutive-adds": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.4.3.tgz", + "integrity": "sha512-8D104wbzzI5RlxeVPYeQb9QsUyepiH1rAO5hpPpQ6NPRgQLpIVwkS/Nbx944pm4K8Z+rx7CgjPsFACz/VCBN0Q==", + "license": "MIT" }, - "node_modules/css.escape": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "node_modules/babel-plugin-transform-member-expression-literals": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.9.4.tgz", + "integrity": "sha512-Xq9/Rarpj+bjOZSl1nBbZYETsNEDDJSrb6Plb1sS3/36FukWFLLRysgecva5KZECjUJTrJoQqjJgtWToaflk5Q==", "license": "MIT" }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "node_modules/babel-plugin-transform-merge-sibling-variables": { + "version": "6.9.5", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.9.5.tgz", + "integrity": "sha512-xj/KrWi6/uP+DrD844h66Qh2cZN++iugEIgH8QcIxhmZZPNP6VpOE9b4gP2FFW39xDAY43kCmYMM6U0QNKN8fw==", + "license": "MIT" + }, + "node_modules/babel-plugin-transform-minify-booleans": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.4.tgz", + "integrity": "sha512-9pW9ePng6DZpzGPalcrULuhSCcauGAbn8AeU3bE34HcDkGm8Ldt0ysjGkyb64f0K3T5ilV4mriayOVv5fg0ASA==", + "license": "MIT" + }, + "node_modules/babel-plugin-transform-property-literals": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.4.tgz", + "integrity": "sha512-Pf8JHTjTPxecqVyL6KSwD/hxGpoTZjiEgV7nCx0KFQsJYM0nuuoCajbg09KRmZWeZbJ5NGTySABYv8b/hY1eEA==", "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" + "dependencies": { + "esutils": "^2.0.2" } }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "node_modules/babel-plugin-transform-regexp-constructors": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.4.3.tgz", + "integrity": "sha512-JjymDyEyRNhAoNFp09y/xGwYVYzT2nWTGrBrWaL6eCg2m+B24qH2jR0AA8V8GzKJTgC8NW6joJmc6nabvWBD/g==", + "license": "MIT" + }, + "node_modules/babel-plugin-transform-remove-console": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.9.4.tgz", + "integrity": "sha512-88blrUrMX3SPiGkT1GnvVY8E/7A+k6oj3MNvUtTIxJflFzXTw1bHkuJ/y039ouhFMp2prRn5cQGzokViYi1dsg==", + "license": "MIT" + }, + "node_modules/babel-plugin-transform-remove-debugger": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.9.4.tgz", + "integrity": "sha512-Kd+eTBYlXfwoFzisburVwrngsrz4xh9I0ppoJnU/qlLysxVBRgI4Pj+dk3X8F5tDiehp3hhP8oarRMT9v2Z3lw==", + "license": "MIT" + }, + "node_modules/babel-plugin-transform-remove-undefined": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.5.0.tgz", + "integrity": "sha512-+M7fJYFaEE/M9CXa0/IRkDbiV3wRELzA1kKQFCJ4ifhrzLKn/9VCCgj9OFmYWwBd8IB48YdgPkHYtbYq+4vtHQ==", "license": "MIT", - "peer": true, "dependencies": { - "css-tree": "~2.2.0" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" + "babel-helper-evaluate-path": "^0.5.0" } }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "node_modules/babel-plugin-transform-simplify-comparison-operators": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.4.tgz", + "integrity": "sha512-GLInxhGAQWJ9YIdjwF6dAFlmh4U+kN8pL6Big7nkDzHoZcaDQOtBm28atEhQJq6m9GpAovbiGEShKqXv4BSp0A==", + "license": "MIT" + }, + "node_modules/babel-plugin-transform-undefined-to-void": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz", + "integrity": "sha512-D2UbwxawEY1xVc9svYAUZQM2xarwSNXue2qDIx6CeV2EuMGaes/0su78zlIDIAgE7BvnMw4UpmSo9fDy+znghg==", + "license": "MIT" + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", "license": "MIT", - "peer": true, "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" } }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "license": "CC0-1.0", - "peer": true - }, - "node_modules/cssstyle": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", - "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", + "node_modules/babel-preset-jest": { + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.4.0.tgz", + "integrity": "sha512-lBY4jxsNmCnSiu7kquw8ZC9F4+XLMOKypT3RnNHPvU2Kpd4W0xaPuLr5ZkRyOsvLYAY4yaW1ZwTW4xB7NIiZzg==", "license": "MIT", "dependencies": { - "@asamuzakjp/css-color": "^3.2.0", - "rrweb-cssom": "^0.8.0" + "babel-plugin-jest-hoist": "30.4.0", + "babel-preset-current-node-syntax": "^1.2.0" }, "engines": { - "node": ">=18" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0 || ^8.0.0-beta.1" } }, - "node_modules/data-uri-to-buffer": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", - "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "node_modules/babel-preset-minify": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-preset-minify/-/babel-preset-minify-0.5.2.tgz", + "integrity": "sha512-v4GL+kk0TfovbRIKZnC3HPbu2cAGmPAby7BsOmuPdMJfHV+4FVdsGXTH/OOGQRKYdjemBuL1+MsE6mobobhe9w==", "license": "MIT", - "engines": { - "node": ">= 14" + "dependencies": { + "babel-plugin-minify-builtins": "^0.5.0", + "babel-plugin-minify-constant-folding": "^0.5.0", + "babel-plugin-minify-dead-code-elimination": "^0.5.2", + "babel-plugin-minify-flip-comparisons": "^0.4.3", + "babel-plugin-minify-guarded-expressions": "^0.4.4", + "babel-plugin-minify-infinity": "^0.4.3", + "babel-plugin-minify-mangle-names": "^0.5.1", + "babel-plugin-minify-numeric-literals": "^0.4.3", + "babel-plugin-minify-replace": "^0.5.0", + "babel-plugin-minify-simplify": "^0.5.1", + "babel-plugin-minify-type-constructors": "^0.4.3", + "babel-plugin-transform-inline-consecutive-adds": "^0.4.3", + "babel-plugin-transform-member-expression-literals": "^6.9.4", + "babel-plugin-transform-merge-sibling-variables": "^6.9.5", + "babel-plugin-transform-minify-booleans": "^6.9.4", + "babel-plugin-transform-property-literals": "^6.9.4", + "babel-plugin-transform-regexp-constructors": "^0.4.3", + "babel-plugin-transform-remove-console": "^6.9.4", + "babel-plugin-transform-remove-debugger": "^6.9.4", + "babel-plugin-transform-remove-undefined": "^0.5.0", + "babel-plugin-transform-simplify-comparison-operators": "^6.9.4", + "babel-plugin-transform-undefined-to-void": "^6.9.4", + "lodash": "^4.17.11" } }, - "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==", - "license": "MIT", - "dependencies": { - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0" + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/bare-events": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.3.tgz", + "integrity": "sha512-HdUm8EMQBLaJvGUdidNNbqpA1kYkwNcb+MYxkxCLAPJGQzlv9J0C24h8V65Z4c5GLd/JEALDvpFCQgpLJqc0zw==", + "license": "Apache-2.0", + "peerDependencies": { + "bare-abort-controller": "*" }, - "engines": { - "node": ">=18" + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } } }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", + "node_modules/bare-fs": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.1.tgz", + "integrity": "sha512-WDRsyVN52eAx/lBamKD6uyw8H4228h/x0sGGGegOamM2cd7Pag88GfMQalobXI+HaEUxpCkbKQUDOQqt9wawRw==", + "license": "Apache-2.0", "dependencies": { - "ms": "^2.1.3" + "bare-events": "^2.5.4", + "bare-path": "^3.0.0", + "bare-stream": "^2.6.4", + "bare-url": "^2.2.2", + "fast-fifo": "^1.3.2" }, "engines": { - "node": ">=6.0" + "bare": ">=1.16.0" + }, + "peerDependencies": { + "bare-buffer": "*" }, "peerDependenciesMeta": { - "supports-color": { + "bare-buffer": { "optional": true } } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "license": "MIT", + "node_modules/bare-os": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.9.1.tgz", + "integrity": "sha512-6M5XjcnsygQNPMCMPXSK379xrJFiZ/AEMNBmFEmQW8d/789VQATvriyi5r0HYTL9TkQ26rn3kgdTG3aisbrXkQ==", + "license": "Apache-2.0", "engines": { - "node": ">=0.10.0" + "bare": ">=1.14.0" } }, - "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==", - "license": "MIT" - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "license": "MIT", - "engines": { - "node": ">=0.10" + "node_modules/bare-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", + "license": "Apache-2.0", + "dependencies": { + "bare-os": "^3.0.1" } }, - "node_modules/decompress": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", - "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", - "license": "MIT", + "node_modules/bare-stream": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.1.tgz", + "integrity": "sha512-Vp0cnjYyrEC4whYTymQ+YZi6pBpfiICZO3cfRG8sy67ZNWe951urv1x4eW1BKNngw3U+3fPYb5JQvHbCtxH7Ow==", + "license": "Apache-2.0", "dependencies": { - "decompress-tar": "^4.0.0", - "decompress-tarbz2": "^4.0.0", - "decompress-targz": "^4.0.0", - "decompress-unzip": "^4.0.1", - "graceful-fs": "^4.1.10", - "make-dir": "^1.0.0", - "pify": "^2.3.0", - "strip-dirs": "^2.0.0" + "streamx": "^2.25.0", + "teex": "^1.0.1" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "bare-abort-controller": "*", + "bare-buffer": "*", + "bare-events": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + }, + "bare-buffer": { + "optional": true + }, + "bare-events": { + "optional": true + } } }, - "node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", - "license": "MIT", + "node_modules/bare-url": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.3.tgz", + "integrity": "sha512-Kccpc7ACfXaxfeInfqKcZtW4pT5YBn1mesc4sCsun6sRwtbJ4h+sNOaksUpYEJUKfN65YWC6Bw2OJEFiKxq8nQ==", + "license": "Apache-2.0", "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" + "bare-path": "^3.0.0" } }, - "node_modules/decompress-tar": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", - "license": "MIT", - "dependencies": { - "file-type": "^5.2.0", - "is-stream": "^1.1.0", - "tar-stream": "^1.5.2" + "node_modules/baseline-browser-mapping": { + "version": "2.10.32", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.32.tgz", + "integrity": "sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" }, "engines": { - "node": ">=4" + "node": ">=6.0.0" } }, - "node_modules/decompress-tar/node_modules/file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", + "node_modules/basic-ftp": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.1.tgz", + "integrity": "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=10.0.0" } }, - "node_modules/decompress-tar/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "node_modules/before-after-hook": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", + "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", + "dev": true, + "license": "Apache-2.0" }, - "node_modules/decompress-tarbz2": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "node_modules/bfj": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-9.1.3.tgz", + "integrity": "sha512-1ythbcNNAd2UjTYW6M+MAHd9KM/m3g4mQ+3a4Vom16WgmUa4GsisdmXAYfpAjkObY5zdpgzaBh1ctZOEcJipuQ==", "license": "MIT", "dependencies": { - "decompress-tar": "^4.1.0", - "file-type": "^6.1.0", - "is-stream": "^1.1.0", - "seek-bzip": "^1.0.5", - "unbzip2-stream": "^1.0.9" + "check-types": "^11.2.3", + "hoopy": "^0.1.4", + "tryer": "^1.0.1" }, "engines": { - "node": ">=4" + "node": ">= 18.0.0" } }, - "node_modules/decompress-tarbz2/node_modules/file-type": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", - "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", + "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==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/decompress-tarbz2/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "license": "MIT", + "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==", "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/decompress-targz": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "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": { - "decompress-tar": "^4.1.1", - "file-type": "^5.2.0", - "is-stream": "^1.1.0" + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" }, "engines": { - "node": ">=4" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/decompress-targz/node_modules/file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", - "license": "MIT", - "engines": { - "node": ">=4" + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" } }, - "node_modules/decompress-targz/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": "*" } }, - "node_modules/decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", "license": "MIT", "dependencies": { - "file-type": "^3.8.0", - "get-stream": "^2.2.0", - "pify": "^2.3.0", - "yauzl": "^2.4.2" + "run-applescript": "^7.0.0" }, "engines": { - "node": ">=4" - } - }, - "node_modules/decompress-unzip/node_modules/file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/decompress-unzip/node_modules/get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", + "node_modules/cacheable": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.5.tgz", + "integrity": "sha512-EQfaKe09tl615iNvq/TBRWTFf1AKJNXYQSsMx0Z3EI0nA+pVsVPS8wJhnRlkbdacKPh1d0qVIhwTc2zsQNFEEg==", "license": "MIT", "dependencies": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" + "@cacheable/memory": "^2.0.8", + "@cacheable/utils": "^2.4.1", + "hookified": "^1.15.0", + "keyv": "^5.6.0", + "qified": "^0.10.1" } }, - "node_modules/decompress-unzip/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "node_modules/cacheable/node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "@keyv/serialize": "^1.1.1" } }, - "node_modules/decompress/node_modules/make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", "license": "MIT", "dependencies": { - "pify": "^3.0.0" + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/decompress/node_modules/make-dir/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, "engines": { - "node": ">=4" + "node": ">= 0.4" } }, - "node_modules/decompress/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/dedent": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", - "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", - "license": "MIT", - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "license": "MIT", "engines": { - "node": ">=4.0.0" + "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==", - "license": "MIT" - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "node_modules/caniuse-lite": { + "version": "1.0.30001793", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz", + "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==", + "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/default-browser": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", - "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", "license": "MIT", "dependencies": { - "bundle-name": "^4.1.0", - "default-browser-id": "^5.0.0" - }, - "engines": { - "node": ">=18" + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser-id": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", - "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", - "license": "MIT", "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10" } }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 16" } }, - "node_modules/degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "node_modules/check-types": { + "version": "11.2.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz", + "integrity": "sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==", + "license": "MIT" + }, + "node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", "license": "MIT", "dependencies": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" + "readdirp": "^5.0.0" }, "engines": { - "node": ">= 14" + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "license": "MIT", + "node_modules/chromium-bidi": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-14.0.0.tgz", + "integrity": "sha512-9gYlLtS6tStdRWzrtXaTMnqcM4dudNegMXJxkR0I/CXObHalYeYcAMPrL19eroNZHtJ8DQmu1E+ZNOYu/IXMXw==", + "license": "Apache-2.0", "dependencies": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" + "mitt": "^3.0.1", + "zod": "^3.24.1" }, - "engines": { - "node": ">=6" + "peerDependencies": { + "devtools-protocol": "*" } }, - "node_modules/del/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "node_modules/cjs-module-lexer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", + "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", + "license": "MIT" + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "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==", - "license": "MIT", + "node_modules/cli-highlight": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", + "dev": true, + "license": "ISC", + "dependencies": { + "chalk": "^4.0.0", + "highlight.js": "^10.7.1", + "mz": "^2.4.0", + "parse5": "^5.1.1", + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" + }, + "bin": { + "highlight": "bin/highlight" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8.0.0", + "npm": ">=5.0.0" } }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "optional": true, - "engines": { - "node": ">=8" + "node_modules/cli-highlight/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/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "node_modules/cli-highlight/node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-highlight/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": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/devtools-protocol": { - "version": "0.0.1581282", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1581282.tgz", - "integrity": "sha512-nv7iKtNZQshSW2hKzYNr46nM/Cfh5SEvE2oV0/SEGgc9XupIY5ggf84Cz8eJIkBce7S3bmTAauFD6aysMpnqsQ==", - "license": "BSD-3-Clause" - }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "node_modules/cli-highlight/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": "Apache-2.0" - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "license": "MIT", "dependencies": { - "path-type": "^4.0.0" + "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": ">=8" + "node": ">=10" } }, - "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==", - "license": "MIT" + "node_modules/cli-highlight/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/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, "license": "MIT", "dependencies": { - "utila": "~0.4" + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" } }, - "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "node_modules/cli-truncate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", + "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", + "dev": true, "license": "MIT", "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" + "slice-ansi": "^8.0.0", + "string-width": "^8.2.0" + }, + "engines": { + "node": ">=20" }, "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "license": "BSD-2-Clause", + "node_modules/cli-truncate/node_modules/string-width": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", + "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } }, - "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "license": "BSD-2-Clause", + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", "dependencies": { - "domelementtype": "^2.2.0" + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">= 4" + "node": ">=20" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" }, "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "license": "BSD-2-Clause", + "node_modules/cliui/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" }, "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-2.1.1.tgz", - "integrity": "sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug==", - "license": "MIT", - "dependencies": { - "no-case": "^2.2.0" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "node_modules/cliui/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "license": "MIT", "dependencies": { - "is-obj": "^2.0.0" + "ansi-regex": "^6.2.2" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/download": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/download/-/download-6.2.5.tgz", - "integrity": "sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA==", + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, "license": "MIT", "dependencies": { - "caw": "^2.0.0", - "content-disposition": "^0.5.2", - "decompress": "^4.0.0", - "ext-name": "^5.0.0", - "file-type": "5.2.0", - "filenamify": "^2.0.0", - "get-stream": "^3.0.0", - "got": "^7.0.0", - "make-dir": "^1.0.0", - "p-event": "^1.0.0", - "pify": "^3.0.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/download/node_modules/file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "license": "MIT", "engines": { - "node": ">=4" + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" } }, - "node_modules/download/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", - "license": "MIT", - "engines": { - "node": ">=4" - } + "node_modules/collect-v8-coverage": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", + "license": "MIT" }, - "node_modules/download/node_modules/make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "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==", "license": "MIT", "dependencies": { - "pify": "^3.0.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">=4" + "node": ">=7.0.0" } }, - "node_modules/download/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "license": "MIT", - "engines": { - "node": ">=4" - } + "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==", + "license": "MIT" }, - "node_modules/drupal-attribute": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/drupal-attribute/-/drupal-attribute-1.2.1.tgz", - "integrity": "sha512-SM0Htd9sBEM08X9/6uqIgm9PzWWKY/Bdef/xsuaTzzzmv6eKPuin1QgwY+Vsp3lX4uYWgrKzXehpp6vqFmpxDQ==", - "license": "MIT License" + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "license": "MIT" }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, "engines": { - "node": ">= 0.4" + "node": ">=18" } }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "readable-stream": "^2.0.2" + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" } }, - "node_modules/duplexer3": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", - "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", - "license": "BSD-3-Clause" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.334", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.334.tgz", - "integrity": "sha512-mgjZAz7Jyx1SRCwEpy9wefDS7GvNPazLthHg8eQMJ76wBdGQQDW33TCrUTvQ4wzpmOrv2zrFoD3oNufMdyMpog==", - "license": "ISC" + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" }, - "node_modules/emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "node_modules/concurrently": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz", + "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==", "license": "MIT", + "dependencies": { + "chalk": "4.1.2", + "rxjs": "7.8.2", + "shell-quote": "1.8.3", + "supports-color": "8.1.1", + "tree-kill": "1.2.2", + "yargs": "17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" } }, - "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==", - "license": "MIT" - }, - "node_modules/emojilib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", - "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", - "dev": true, - "license": "MIT" + "node_modules/concurrently/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">= 4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "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==", + "node_modules/concurrently/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==", "license": "MIT", "dependencies": { - "once": "^1.4.0" + "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/enhanced-resolve": { - "version": "5.20.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz", - "integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==", + "node_modules/concurrently/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.3.0" + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=10.13.0" + "node": ">=12" } }, - "node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "license": "BSD-2-Clause", + "node_modules/concurrently/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", "engines": { - "node": ">=0.12" + "node": ">=12" + } + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/config-chain/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/consola": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", + "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==", + "license": "MIT" + }, + "node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" }, "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/env-ci": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-11.2.0.tgz", - "integrity": "sha512-D5kWfzkmaOQDioPmiviWAVtKmpPT4/iJmMVQxWxMPJTFyTkdc5JQUfc5iXEeWxcOdsYTKSAiA/Age4NUOqKsRA==", + "node_modules/conventional-changelog-angular": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.3.1.tgz", + "integrity": "sha512-6gfI3otXK5Ph5DfCOI1dblr+kN3FAm5a97hYoQkqNZxOaYa5WKfXH+AnpsmS+iUH2mgVC2Cg2Qw9m5OKcmNrIg==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "execa": "^8.0.0", - "java-properties": "^1.0.2" + "compare-func": "^2.0.0" }, "engines": { - "node": "^18.17 || >=20.6.1" + "node": ">=18" } }, - "node_modules/env-ci/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "node_modules/conventional-changelog-conventionalcommits": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-9.3.1.tgz", + "integrity": "sha512-dTYtpIacRpcZgrvBYvBfArMmK2xvIpv2TaxM0/ZI5CBtNUzvF2x0t15HsbRABWprS6UPmvj+PzHVjSx4qAVKyw==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" + "compare-func": "^2.0.0" }, "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "node": ">=18" } }, - "node_modules/env-ci/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "node_modules/conventional-changelog-writer": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-8.4.0.tgz", + "integrity": "sha512-HHBFkk1EECxxmCi4CTu091iuDpQv5/OavuCUAuZmrkWpmYfyD816nom1CvtfXJ/uYfAAjavgHvXHX291tSLK8g==", "dev": true, "license": "MIT", + "dependencies": { + "@simple-libs/stream-utils": "^1.2.0", + "conventional-commits-filter": "^5.0.0", + "handlebars": "^4.7.7", + "meow": "^13.0.0", + "semver": "^7.5.2" + }, + "bin": { + "conventional-changelog-writer": "dist/cli/index.js" + }, "engines": { - "node": ">=16" + "node": ">=18" + } + }, + "node_modules/conventional-changelog-writer/node_modules/semver": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=10" } }, - "node_modules/env-ci/node_modules/human-signals": { + "node_modules/conventional-commits-filter": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-5.0.0.tgz", + "integrity": "sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "engines": { - "node": ">=16.17.0" + "node": ">=18" } }, - "node_modules/env-ci/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "node_modules/conventional-commits-parser": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.4.0.tgz", + "integrity": "sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw==", "dev": true, "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "dependencies": { + "@simple-libs/stream-utils": "^1.2.0", + "meow": "^13.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "bin": { + "conventional-commits-parser": "dist/cli/index.js" + }, + "engines": { + "node": ">=18" } }, - "node_modules/env-ci/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "node_modules/convert-hrtime": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-5.0.0.tgz", + "integrity": "sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==", "dev": true, "license": "MIT", "engines": { @@ -11070,70 +8907,98 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/env-ci/node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", - "dev": 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==", + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", "license": "MIT", "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "browserslist": "^4.28.1" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, - "node_modules/env-ci/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true, + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", + "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", "license": "MIT", "dependencies": { - "mimic-fn": "^4.0.0" + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" }, "engines": { - "node": ">=12" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/env-ci/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "node_modules/cosmiconfig-typescript-loader": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.3.0.tgz", + "integrity": "sha512-Akr82WH1Wfqatyiqpj8HDkO2o2KmJRu1FhKfSNJP3K4IdXwHfEyL7MOb62i1AGQVLtIQM+iCE9CGOtrfhR+mmA==", "dev": true, "license": "MIT", + "dependencies": { + "jiti": "2.6.1" + }, "engines": { - "node": ">=12" + "node": ">=v18" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=9", + "typescript": ">=5" } }, - "node_modules/env-ci/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" + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": ">= 8" } }, - "node_modules/env-ci/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", "license": "MIT", + "dependencies": { + "type-fest": "^1.0.1" + }, "engines": { "node": ">=12" }, @@ -11141,1253 +9006,1372 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "license": "MIT", + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/envinfo": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", - "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", + "node_modules/css-functions-list": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.3.3.tgz", + "integrity": "sha512-8HFEBPKhOpJPEPu70wJJetjKta86Gw9+CCyCnB3sui2qQfOvRyqBy4IKLKKAwdMpWb2lHXWk9Wb4Z6AmaUT1Pg==", "license": "MIT", - "bin": { - "envinfo": "dist/cli.js" - }, "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/environment": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", - "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", - "license": "MIT", - "engines": { - "node": ">=18" + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/error-ex": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", "license": "MIT", "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, "engines": { - "node": ">= 0.4" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", "engines": { - "node": ">= 0.4" + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "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==", + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", "license": "MIT" }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" + "bin": { + "cssesc": "bin/cssesc" }, "engines": { - "node": ">= 0.4" + "node": ">=4" } }, - "node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "hasInstallScript": true, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" + "dependencies": { + "css-tree": "~2.2.0" }, "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" } }, - "node_modules/esbuild-register": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz", - "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==", + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", "license": "MIT", "dependencies": { - "debug": "^4.3.4" + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" }, - "peerDependencies": { - "esbuild": ">=0.12 <1" + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" } }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" + }, + "node_modules/cssstyle": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", + "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^3.2.0", + "rrweb-cssom": "^0.8.0" + }, "engines": { - "node": ">=6" + "node": ">=18" } }, - "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==", + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 14" } }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "license": "BSD-2-Clause", + "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==", + "license": "MIT", "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" }, "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" + "node": ">=18" } }, - "node_modules/eslint": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.2.0.tgz", - "integrity": "sha512-+L0vBFYGIpSNIt/KWTpFonPrqYvgKw1eUI5Vn7mEogrQcWtWYtNQ7dNqC+px/J0idT3BAkiWrhfS7k+Tum8TUA==", + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.2", - "@eslint/config-array": "^0.23.4", - "@eslint/config-helpers": "^0.5.4", - "@eslint/core": "^1.2.0", - "@eslint/plugin-kit": "^0.7.0", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "ajv": "^6.14.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^9.1.2", - "eslint-visitor-keys": "^5.0.1", - "espree": "^11.2.0", - "esquery": "^1.7.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", - "minimatch": "^10.2.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">= 0.4" }, "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-config-prettier": { - "version": "10.1.8", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", - "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" }, - "funding": { - "url": "https://opencollective.com/eslint-config-prettier" + "engines": { + "node": ">= 0.4" }, - "peerDependencies": { - "eslint": ">=7.0.0" + "funding": { + "url": "https://github.com/sponsors/inspect-js" } }, - "node_modules/eslint-plugin-jest": { - "version": "29.15.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.2.tgz", - "integrity": "sha512-kEN4r9RZl1xcsb4arGq89LrcVdOUFII/JSCwtTPJyv16mDwmPrcuEQwpxqZHeINvcsd7oK5O/rhdGlxFRaZwvQ==", + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "^8.0.0" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { - "node": "^20.12.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^8.0.0", - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "jest": "*", - "typescript": ">=4.8.4 <7.0.0" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "jest": { - "optional": true - }, - "typescript": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-prettier": { - "version": "5.5.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.5.tgz", - "integrity": "sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==", + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { - "prettier-linter-helpers": "^1.0.1", - "synckit": "^0.11.12" + "ms": "^2.1.3" }, "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" + "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==", + "license": "MIT" + }, + "node_modules/dedent": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", + "license": "MIT", "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", - "prettier": ">=3.0.0" + "babel-plugin-macros": "^3.1.0" }, "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { + "babel-plugin-macros": { "optional": true } } }, - "node_modules/eslint-plugin-security": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-security/-/eslint-plugin-security-4.0.0.tgz", - "integrity": "sha512-tfuQT8K/Li1ZxhFzyD8wPIKtlzZxqBcPr9q0jFMQ77wWAbKBVEhaMPVQRTMTvCMUDhwBe5vPVqQPwAGk/ASfxQ==", - "license": "Apache-2.0", - "dependencies": { - "safe-regex": "^2.1.1" - }, + "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==", + "license": "MIT", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=6" } }, - "node_modules/eslint-scope": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", - "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", - "license": "BSD-2-Clause", + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-browser": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", + "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", + "license": "MIT", "dependencies": { - "@types/esrecurse": "^4.3.1", - "@types/estree": "^1.0.8", - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">=18" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-visitor-keys": { + "node_modules/default-browser-id": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "license": "MIT", "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">=18" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint/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==", - "license": "MIT" + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/espree": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", - "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", - "license": "BSD-2-Clause", + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", "dependencies": { - "acorn": "^8.16.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^5.0.1" + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" }, "engines": { - "node": ">=4" + "node": ">= 14" } }, - "node_modules/esquery": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", - "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", "engines": { - "node": ">=0.10" + "node": ">=6" } }, - "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==", - "license": "BSD-2-Clause", + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.1608973", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1608973.tgz", + "integrity": "sha512-Tpm17fxYzt+J7VrGdc1k8YdRqS3YV7se/M6KeemEqvUbq/n7At1rWVuXMxQgpWkdwSdIEKYbU//Bve+Shm4YNQ==", + "license": "BSD-3-Clause" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", "dependencies": { - "estraverse": "^5.2.0" + "path-type": "^4.0.0" }, "engines": { - "node": ">=4.0" + "node": ">=8" } }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, "engines": { - "node": ">=4.0" + "node": ">=0.10.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==", + "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==", + "license": "MIT", + "peer": true + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "license": "MIT", "dependencies": { - "@types/estree": "^1.0.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/dom-serializer/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "license": "BSD-2-Clause", "engines": { - "node": ">=0.10.0" + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/eventemitter3": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", - "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", - "dev": true, - "license": "MIT" + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "license": "MIT", + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, "engines": { - "node": ">=0.8.x" + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/events-universal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", - "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", - "license": "Apache-2.0", + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", "dependencies": { - "bare-events": "^2.7.0" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/exec-buffer": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/exec-buffer/-/exec-buffer-3.2.0.tgz", - "integrity": "sha512-wsiD+2Tp6BWHoVv3B+5Dcx6E7u5zky+hUwOHjuH2hKSLR3dvRmX8fk8UD8uqQixHs4Wk6eDmiegVrMPjKj7wpA==", + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, "license": "MIT", "dependencies": { - "execa": "^0.7.0", - "p-finally": "^1.0.0", - "pify": "^3.0.0", - "rimraf": "^2.5.4", - "tempfile": "^2.0.0" + "is-obj": "^2.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/exec-buffer/node_modules/cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/exec-buffer/node_modules/execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", - "license": "MIT", + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=4" + "readable-stream": "^2.0.2" } }, - "node_modules/exec-buffer/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "node_modules/electron-to-chromium": { + "version": "1.5.361", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.361.tgz", + "integrity": "sha512-Q6Hts7N9FnJc5LeGRINFvLhCI9xZmNtTDe5ZbcVezQz7cU4a8Aua3GH1b8J2XY8Al9PF+OCwYqhgsOOheMdvkA==", + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/exec-buffer/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "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==", + "license": "MIT" + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/empathic": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.1.tgz", + "integrity": "sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==", "license": "MIT", "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/exec-buffer/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "license": "ISC", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "node": ">=14" } }, - "node_modules/exec-buffer/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "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==", "license": "MIT", "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" + "once": "^1.4.0" } }, - "node_modules/exec-buffer/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "license": "MIT", + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", "engines": { - "node": ">=4" + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/exec-buffer/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "node_modules/env-ci": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-11.2.0.tgz", + "integrity": "sha512-D5kWfzkmaOQDioPmiviWAVtKmpPT4/iJmMVQxWxMPJTFyTkdc5JQUfc5iXEeWxcOdsYTKSAiA/Age4NUOqKsRA==", + "dev": true, "license": "MIT", + "dependencies": { + "execa": "^8.0.0", + "java-properties": "^1.0.2" + }, "engines": { - "node": ">=4" + "node": "^18.17 || >=20.6.1" } }, - "node_modules/exec-buffer/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "node_modules/env-ci/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, "license": "MIT", "dependencies": { - "shebang-regex": "^1.0.0" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/exec-buffer/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "node_modules/env-ci/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/exec-buffer/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" + "node": ">=16" }, - "bin": { - "which": "bin/which" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/exec-buffer/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "license": "ISC" + "node_modules/env-ci/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/env-ci/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/execa/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "node_modules/env-ci/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, "license": "MIT", "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/executable": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", - "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "node_modules/env-ci/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, "license": "MIT", "dependencies": { - "pify": "^2.2.0" + "path-key": "^4.0.0" }, "engines": { - "node": ">=4" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/executable/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "node_modules/env-ci/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/exit-x": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", - "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", + "node_modules/env-ci/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.8.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", - "license": "MIT", - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, + "node_modules/env-ci/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": ">=0.10.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/expect": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.3.0.tgz", - "integrity": "sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==", + "node_modules/env-ci/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, "license": "MIT", - "dependencies": { - "@jest/expect-utils": "30.3.0", - "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.3.0", - "jest-message-util": "30.3.0", - "jest-mock": "30.3.0", - "jest-util": "30.3.0" - }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ext-list": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", - "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "license": "MIT", - "dependencies": { - "mime-db": "^1.28.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/ext-name": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", - "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "node_modules/envinfo": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", + "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", "license": "MIT", - "dependencies": { - "ext-list": "^2.0.0", - "sort-keys-length": "^1.0.0" + "bin": { + "envinfo": "dist/cli.js" }, "engines": { "node": ">=4" } }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", "dev": true, "license": "MIT", - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "license": "BSD-2-Clause", + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "license": "MIT", "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" + "is-arrayish": "^0.2.1" } }, - "node_modules/extract-zip/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "node_modules/es-abstract": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", "license": "MIT", "dependencies": { - "pump": "^3.0.0" + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fast-content-type-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", - "integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "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==", - "license": "MIT" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "license": "Apache-2.0" - }, - "node_modules/fast-equals": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.4.0.tgz", - "integrity": "sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw==", + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", "engines": { - "node": ">=6.0.0" + "node": ">= 0.4" } }, - "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==", - "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==", + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "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==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, "engines": { - "node": ">= 6" + "node": ">= 0.4" } }, - "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==", - "license": "MIT" - }, - "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==", - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "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==", + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/fastq": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", - "license": "ISC", "dependencies": { - "reusify": "^1.0.4" + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "license": "Apache-2.0", + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", "dependencies": { - "bser": "2.1.1" + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/fd-slicer": { + "node_modules/es-shim-unscopables": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", "license": "MIT", "dependencies": { - "pend": "~1.2.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "license": "MIT", "dependencies": { - "escape-string-regexp": "^1.0.5" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/es-toolkit": { + "version": "1.46.1", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.46.1.tgz", + "integrity": "sha512-5eNtXOs3tbfxXOj04tjjseeWkRWaoCjdEI+96DgwzZoe6c9juL49pXlzAFTI72aWC9Y8p7168g6XIKjh7k6pyQ==", "dev": true, "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, + "node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, "engines": { - "node": ">=0.8.0" + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" } }, - "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==", + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "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==", "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", "dependencies": { - "flat-cache": "^4.0.0" + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" }, "engines": { - "node": ">=16.0.0" + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" } }, - "node_modules/file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "node_modules/eslint": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "license": "MIT", "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "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.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" }, "engines": { - "node": ">= 10.13.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://eslint.org/donate" }, "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/file-loader/node_modules/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "node_modules/eslint-config-prettier": { + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "bin": { + "eslint-config-prettier": "bin/cli.js" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://opencollective.com/eslint-config-prettier" + }, + "peerDependencies": { + "eslint": ">=7.0.0" } }, - "node_modules/file-loader/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "node_modules/eslint-import-resolver-node": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz", + "integrity": "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==", "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.16.1", + "resolve": "^2.0.0-next.6" } }, - "node_modules/file-loader/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==", - "license": "MIT" - }, - "node_modules/file-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "ms": "^2.1.1" } }, - "node_modules/file-type": { - "version": "19.6.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-19.6.0.tgz", - "integrity": "sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ==", + "node_modules/eslint-import-resolver-node/node_modules/resolve": { + "version": "2.0.0-next.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz", + "integrity": "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==", "license": "MIT", "dependencies": { - "get-stream": "^9.0.1", - "strtok3": "^9.0.1", - "token-types": "^6.0.0", - "uint8array-extras": "^1.3.0" + "es-errors": "^1.3.0", + "is-core-module": "^2.16.2", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sindresorhus/file-type?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/file-type/node_modules/get-stream": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", - "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", "license": "MIT", "dependencies": { - "@sec-ant/readable-stream": "^0.4.1", - "is-stream": "^4.0.1" + "debug": "^3.2.7" }, "engines": { - "node": ">=18" + "node": ">=4" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/file-type/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "ms": "^2.1.1" } }, - "node_modules/filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, "engines": { "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, - "node_modules/filenamify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz", - "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==", + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", "dependencies": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.0", - "trim-repeated": "^1.0.0" - }, - "engines": { - "node": ">=4" + "ms": "^2.1.1" } }, - "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==", + "node_modules/eslint-plugin-import/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "license": "MIT", "dependencies": { - "to-regex-range": "^5.0.1" + "minimist": "^1.2.0" }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/eslint-plugin-import/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=4" } }, - "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==", + "node_modules/eslint-plugin-import/node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "license": "MIT", "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" } }, - "node_modules/find-up-simple": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", - "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", - "dev": true, + "node_modules/eslint-plugin-jest": { + "version": "29.15.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.2.tgz", + "integrity": "sha512-kEN4r9RZl1xcsb4arGq89LrcVdOUFII/JSCwtTPJyv16mDwmPrcuEQwpxqZHeINvcsd7oK5O/rhdGlxFRaZwvQ==", "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.0.0" + }, "engines": { - "node": ">=18" + "node": "^20.12.0 || ^22.0.0 || >=24.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^8.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "jest": "*", + "typescript": ">=4.8.4 <7.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + }, + "typescript": { + "optional": true + } } }, - "node_modules/find-versions": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz", - "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==", + "node_modules/eslint-plugin-prettier": { + "version": "5.5.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.5.tgz", + "integrity": "sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==", "license": "MIT", "dependencies": { - "semver-regex": "^2.0.0" + "prettier-linter-helpers": "^1.0.1", + "synckit": "^0.11.12" }, "engines": { - "node": ">=6" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } } }, - "node_modules/findup-sync": { + "node_modules/eslint-plugin-security": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", - "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", - "license": "MIT", + "resolved": "https://registry.npmjs.org/eslint-plugin-security/-/eslint-plugin-security-4.0.0.tgz", + "integrity": "sha512-tfuQT8K/Li1ZxhFzyD8wPIKtlzZxqBcPr9q0jFMQ77wWAbKBVEhaMPVQRTMTvCMUDhwBe5vPVqQPwAGk/ASfxQ==", + "license": "Apache-2.0", "dependencies": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^4.0.2", - "resolve-dir": "^1.0.1" + "safe-regex": "^2.1.1" }, "engines": { - "node": ">= 8" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "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==", + "node_modules/eslint-plugin-storybook": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-10.4.1.tgz", + "integrity": "sha512-sLEvd/7lg/LtXwMjj3iFxZtoeAC/8l1Qhuw3Noa8iF8i0UIgAejUs7k6DNSqHkwrPR8caWT4+3fxdMXs1iGLTg==", "license": "MIT", "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" + "@typescript-eslint/utils": "^8.48.0" }, - "engines": { - "node": ">=16" + "peerDependencies": { + "eslint": ">=8", + "storybook": "^10.4.1" } }, - "node_modules/flatted": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", - "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", - "license": "ISC" - }, - "node_modules/for-each": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", - "license": "MIT", + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", "dependencies": { - "is-callable": "^1.2.7" + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8.0.0" } }, - "node_modules/foreachasync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/foreachasync/-/foreachasync-3.0.0.tgz", - "integrity": "sha512-J+ler7Ta54FwwNcx6wQRDhTIbNeyDcARMkOcguEqnEdtm0jKvN3Li3PDAb2Du3ubJYEWfYL83XMROXdsXAXycw==", - "license": "Apache2" - }, - "node_modules/fork-ts-checker-webpack-plugin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz", - "integrity": "sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.16.7", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "cosmiconfig": "^7.0.1", - "deepmerge": "^4.2.2", - "fs-extra": "^10.0.0", - "memfs": "^3.4.1", - "minimatch": "^3.0.4", - "node-abort-controller": "^3.0.1", - "schema-utils": "^3.1.1", - "semver": "^7.3.5", - "tapable": "^2.2.1" - }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "license": "Apache-2.0", "engines": { - "node": ">=12.13.0", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "typescript": ">3.6.0", - "webpack": "^5.11.0" + "node": ">=10" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "node_modules/eslint/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -12400,418 +10384,448 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/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==", - "license": "MIT" - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "license": "MIT", + "node_modules/eslint/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==", + "license": "BSD-2-Clause", "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "node_modules/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==", + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", "engines": { - "node": ">=12" + "node": ">=4.0" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/json-schema-traverse": { + "node_modules/eslint/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==", "license": "MIT" }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "license": "ISC", + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "license": "BSD-2-Clause", "dependencies": { - "brace-expansion": "^1.1.7" + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": "*" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, + "node_modules/espree/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==", + "license": "Apache-2.0", "engines": { - "node": ">= 10.13.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://opencollective.com/eslint" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "license": "ISC", + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", "bin": { - "semver": "bin/semver.js" + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" }, "engines": { - "node": ">=10" + "node": ">=4" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/yaml": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", - "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", - "license": "ISC", + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, "engines": { - "node": ">= 6" + "node": ">=0.10" } }, - "node_modules/fraction.js": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", - "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", - "license": "MIT", + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", "engines": { - "node": "*" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/rawify" + "node": ">=4.0" } }, - "node_modules/from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", - "license": "MIT", + "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==", + "license": "BSD-2-Clause", "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "license": "MIT" + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } }, - "node_modules/fs-extra": { - "version": "11.3.4", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", - "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", "engines": { - "node": ">=14.14" + "node": ">=4.0" } }, - "node_modules/fs-monkey": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.1.0.tgz", - "integrity": "sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==", - "license": "Unlicense" + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=0.10.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==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" } }, - "node_modules/function-timeout": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/function-timeout/-/function-timeout-1.0.2.tgz", - "integrity": "sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==", + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/generator-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", - "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "node_modules/exit-x": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", + "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">= 0.8.0" } }, - "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==", + "node_modules/expect": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.4.1.tgz", + "integrity": "sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==", "license": "MIT", + "dependencies": { + "@jest/expect-utils": "30.4.1", + "@jest/get-type": "30.1.0", + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-util": "30.4.1" + }, "engines": { - "node": ">=6.9.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.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==", - "license": "ISC", + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" } }, - "node_modules/get-east-asian-width": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", - "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, "engines": { - "node": ">=18" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-intrinsic": { + "node_modules/fast-content-type-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", + "integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "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==", + "license": "MIT" + }, + "node_modules/fast-diff": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "license": "Apache-2.0" + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "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==", "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" + "@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" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": ">=8.6.0" } }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", + "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==", + "license": "ISC", "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" + "is-glob": "^4.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">= 6" } }, - "node_modules/get-proxy": { + "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz", - "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "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==", "license": "MIT", - "dependencies": { - "npm-conf": "^1.1.0" - }, "engines": { - "node": ">=4" + "node": ">= 4.9.1" } }, - "node_modules/get-stream": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", - "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" } }, - "node_modules/get-uri": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", - "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", - "license": "MIT", + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "license": "Apache-2.0", "dependencies": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" + "bser": "2.1.1" } }, - "node_modules/git-log-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.1.tgz", - "integrity": "sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ==", - "dev": true, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "license": "MIT", "dependencies": { - "argv-formatter": "~1.0.0", - "spawn-error-forwarder": "~1.0.0", - "split2": "~1.0.0", - "stream-combiner2": "~1.1.1", - "through2": "~2.0.0", - "traverse": "0.6.8" + "pend": "~1.2.0" } }, - "node_modules/git-raw-commits": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-5.0.1.tgz", - "integrity": "sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==", - "dev": true, + "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==", "license": "MIT", "dependencies": { - "@conventional-changelog/git-client": "^2.6.0", - "meow": "^13.0.0" - }, - "bin": { - "git-raw-commits": "src/cli.js" + "flat-cache": "^4.0.0" }, "engines": { - "node": ">=18" + "node": ">=16.0.0" } }, - "node_modules/glob": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", - "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", - "license": "BlueOak-1.0.0", + "node_modules/file-type": { + "version": "21.3.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.4.tgz", + "integrity": "sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==", + "license": "MIT", "dependencies": { - "minimatch": "^10.2.2", - "minipass": "^7.1.3", - "path-scurry": "^2.0.2" + "@tokenizer/inflate": "^0.4.1", + "strtok3": "^10.3.4", + "token-types": "^6.1.1", + "uint8array-extras": "^1.4.0" }, "engines": { - "node": "18 || 20 || >=22" + "node": ">=20" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sindresorhus/file-type?sponsor=1" } }, - "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==", - "license": "ISC", + "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==", + "license": "MIT", "dependencies": { - "is-glob": "^4.0.3" + "to-regex-range": "^5.0.1" }, "engines": { - "node": ">=10.13.0" + "node": ">=8" } }, - "node_modules/glob-to-regex.js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz", - "integrity": "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==", - "license": "Apache-2.0", + "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==", + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, "engines": { - "node": ">=10.0" + "node": ">=10" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "license": "BSD-2-Clause" - }, - "node_modules/global-directory": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", - "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "node_modules/find-up-simple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", "dev": true, "license": "MIT", - "dependencies": { - "ini": "4.1.1" - }, "engines": { "node": ">=18" }, @@ -12819,90 +10833,50 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "node_modules/find-versions": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-6.0.0.tgz", + "integrity": "sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA==", + "dev": true, "license": "MIT", "dependencies": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" + "semver-regex": "^4.0.5", + "super-regex": "^1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "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==", "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" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": ">=0.10.0" + "node": ">=16" } }, - "node_modules/global-prefix/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "license": "ISC" }, - "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==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "license": "MIT", "dependencies": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "is-callable": "^1.2.7" }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/globby/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/globjoin": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", - "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", - "license": "MIT" - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -12910,121 +10884,88 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "license": "MIT", - "dependencies": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/got/node_modules/get-stream": { + "node_modules/foreachasync": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/got/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "resolved": "https://registry.npmjs.org/foreachasync/-/foreachasync-3.0.0.tgz", + "integrity": "sha512-J+ler7Ta54FwwNcx6wQRDhTIbNeyDcARMkOcguEqnEdtm0jKvN3Li3PDAb2Du3ubJYEWfYL83XMROXdsXAXycw==", + "license": "Apache2" }, - "node_modules/got/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "node_modules/fraction.js": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" } }, - "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==", - "license": "ISC" - }, - "node_modules/handlebars": { - "version": "4.7.9", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", - "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", - "dev": true, + "node_modules/fs-extra": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.5.tgz", + "integrity": "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==", "license": "MIT", "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" + "node": ">=14.14" } }, - "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==", + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "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==", "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "node_modules/function-timeout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/function-timeout/-/function-timeout-1.0.2.tgz", + "integrity": "sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==", + "dev": true, "license": "MIT", "engines": { - "node": "*" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, "engines": { "node": ">= 0.4" }, @@ -13032,725 +10973,694 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "license": "MIT", - "dependencies": { - "has-symbol-support-x": "^1.4.1" - }, - "engines": { - "node": "*" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hashery": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz", - "integrity": "sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==", + "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==", "license": "MIT", - "dependencies": { - "hookified": "^1.15.0" - }, "engines": { - "node": ">=20" + "node": ">=6.9.0" } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, + "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==", + "license": "ISC", "engines": { - "node": ">= 0.4" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", "license": "MIT", - "bin": { - "he": "bin/he" + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/header-case": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/header-case/-/header-case-1.0.1.tgz", - "integrity": "sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==", + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.1.3" + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", - "dev": true, - "license": "BSD-3-Clause", + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "license": "MIT", "engines": { - "node": "*" + "node": ">=8.0.0" } }, - "node_modules/homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { - "parse-passwd": "^1.0.0" + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/hook-std": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-4.0.0.tgz", - "integrity": "sha512-IHI4bEVOt3vRUDJ+bFA9VUJlo7SzvFARPNLw75pqSmAOP2HmTWfFJtPvLBrDrlgjEYXY9zs7SFdHPQaJShkSCQ==", - "dev": true, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "license": "MIT", "engines": { - "node": ">=20" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/hookified": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz", - "integrity": "sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==", - "license": "MIT" - }, - "node_modules/hoopy": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", - "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, "engines": { - "node": ">= 6.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hosted-git-info": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", - "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", - "dev": true, - "license": "ISC", + "node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "license": "MIT", "dependencies": { - "lru-cache": "^10.0.1" + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": ">= 14" } }, - "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "node_modules/git-log-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.1.tgz", + "integrity": "sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ==", "dev": true, - "license": "ISC" + "license": "MIT", + "dependencies": { + "argv-formatter": "~1.0.0", + "spawn-error-forwarder": "~1.0.0", + "split2": "~1.0.0", + "stream-combiner2": "~1.1.1", + "through2": "~2.0.0", + "traverse": "0.6.8" + } }, - "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==", + "node_modules/git-raw-commits": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-5.0.1.tgz", + "integrity": "sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==", + "dev": true, "license": "MIT", "dependencies": { - "whatwg-encoding": "^3.1.1" + "@conventional-changelog/git-client": "^2.6.0", + "meow": "^13.0.0" + }, + "bin": { + "git-raw-commits": "src/cli.js" }, "engines": { "node": ">=18" } }, - "node_modules/html-entities": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", - "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ], - "license": "MIT" - }, - "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==", - "license": "MIT" + "node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "license": "MIT", + "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==", + "license": "ISC", "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" + "is-glob": "^4.0.3" }, "engines": { - "node": ">=12" + "node": ">=10.13.0" } }, - "node_modules/html-minifier-terser/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "node_modules/glob/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", "engines": { - "node": ">= 12" + "node": "18 || 20 || >=22" } }, - "node_modules/html-tags": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-5.1.0.tgz", - "integrity": "sha512-n6l5uca7/y5joxZ3LUePhzmBFUJ+U2YWzhMa8XUTecSeSlQiZdF5XAd/Q3/WUl0VsXgUwWi8I7CNIwdI5WN1SQ==", + "node_modules/glob/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "license": "MIT", - "engines": { - "node": ">=20.10" + "dependencies": { + "balanced-match": "^4.0.2" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "18 || 20 || >=22" } }, - "node_modules/html-webpack-plugin": { - "version": "5.6.6", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.6.tgz", - "integrity": "sha512-bLjW01UTrvoWTJQL5LsMRo1SypHW80FTm12OJRSnr3v6YHNhfe+1r0MYUZJMACxnCHURVnBWRwAsWs2yPU9Ezw==", - "license": "MIT", + "node_modules/glob/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=10.13.0" + "node": "18 || 20 || >=22" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.20.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], + "node_modules/global-directory": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-5.0.0.tgz", + "integrity": "sha512-1pgFdhK3J2LeM+dVf2Pd424yHx2ou338lC0ErNP2hPx4j8eW1Sp0XqSjNxtk6Tc4Kr5wlWtSvz8cn2yb7/SG/w==", + "dev": true, "license": "MIT", "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "node_modules/htmlparser2/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "license": "BSD-2-Clause", + "ini": "6.0.0" + }, + "engines": { + "node": ">=20" + }, "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/http-cache-semantics": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", - "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", - "license": "BSD-2-Clause" - }, - "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==", + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "license": "MIT", "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" + "global-prefix": "^3.0.0" }, "engines": { - "node": ">= 14" + "node": ">=6" } }, - "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==", + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "license": "MIT", "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" }, "engines": { - "node": ">= 14" + "node": ">=6" } }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" + "node_modules/global-prefix/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "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==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" } }, - "node_modules/husky": { - "version": "9.1.7", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", - "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", - "dev": true, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "license": "MIT", - "bin": { - "husky": "bin.js" - }, "engines": { "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, - "node_modules/hyperdyperid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", - "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", - "license": "MIT", - "engines": { - "node": ">=10.18" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "license": "ISC", - "engines": { - "node": "^10 || ^12 || >= 14" + "node": ">= 0.4" }, - "peerDependencies": { - "postcss": "^8.1.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/identifier-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/identifier-regex/-/identifier-regex-1.0.1.tgz", - "integrity": "sha512-ZrYyM0sozNPZlvBvE7Oq9Bn44n0qKGrYu5sQ0JzMUnjIhpgWYE2JB6aBoFwEYdPjqj7jPyxXTMJiHDOxDfd8yw==", + "node_modules/globby": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-16.2.0.tgz", + "integrity": "sha512-QrJia2qDf5BB/V6HYlDTs0I0lBahyjLzpGQg3KT7FnCdTonAyPy2RtY802m2k4ALx6Dp752f82WsOczEVr3l6Q==", "license": "MIT", "dependencies": { - "reserved-identifiers": "^1.0.0" + "@sindresorhus/merge-streams": "^4.0.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.5", + "is-path-inside": "^4.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.4.0" }, "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "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==", + "node_modules/globby/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "license": "MIT", "engines": { "node": ">= 4" } }, - "node_modules/image-dimensions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/image-dimensions/-/image-dimensions-2.5.0.tgz", - "integrity": "sha512-CKZPHjAEtSg9lBV9eER0bhNn/yrY7cFEQEhkwjLhqLY+Na8lcP1pEyWsaGMGc8t2qbKWA/tuqbhFQpOKGN72Yw==", + "node_modules/globby/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "license": "MIT", - "bin": { - "image-dimensions": "cli.js" - }, "engines": { - "node": ">=18" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/image-minimizer-webpack-plugin": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/image-minimizer-webpack-plugin/-/image-minimizer-webpack-plugin-5.0.0.tgz", - "integrity": "sha512-TSeES2mTBY1smDnQRIaTGR9EdS1xGvWsaMu+XJRlh6z7VAWHmyYR6P5AynvVHMcmK4NdvmSlRJTNWgvpeNSPuA==", + "node_modules/globby/node_modules/unicorn-magic": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", + "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", "license": "MIT", - "dependencies": { - "schema-utils": "^4.2.0", - "serialize-javascript": "^7.0.3" - }, "engines": { - "node": ">= 20.9.0" + "node": ">=20" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "license": "MIT" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" }, - "peerDependencies": { - "webpack": "^5.1.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" }, - "peerDependenciesMeta": { - "@squoosh/lib": { - "optional": true - }, - "imagemin": { - "optional": true - }, - "sharp": { - "optional": true - }, - "svgo": { - "optional": true - } + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" } }, - "node_modules/imagemin": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-9.0.1.tgz", - "integrity": "sha512-UoHOfynN8QeqRoUGunn6ilMnLpJ+utbmleP2ufcFqaGal8mY/PeOpV43N31uqtb+CBMFqQ7hxgKzIaAAnmcrdA==", - "license": "MIT", - "dependencies": { - "change-file-extension": "^0.1.1", - "environment": "^1.0.0", - "file-type": "^19.0.0", - "globby": "^14.0.1", - "image-dimensions": "^2.3.0", - "junk": "^4.0.1", - "ow": "^2.0.0", - "p-pipe": "^4.0.0", - "slash": "^5.1.0", - "uint8array-extras": "^1.1.0" - }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "license": "MIT", "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/imagemin-jpegtran": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/imagemin-jpegtran/-/imagemin-jpegtran-8.0.0.tgz", - "integrity": "sha512-iGaaImltX4oJ1lmS9jb7Qw3NRusQnVBr7hYJuhyL0CHRV42pDMkIGBVCHKA9j9mcWHnO5Ryu3LV7t4fU4sC4xg==", + "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==", "license": "MIT", - "dependencies": { - "execa": "^9.4.0", - "file-type": "^19.5.0", - "image-dimensions": "^2.3.0", - "jpegtran-bin": "^7.0.0", - "uint8array-extras": "^1.4.0" - }, "engines": { - "node": ">=18" + "node": ">=8" } }, - "node_modules/imagemin-jpegtran/node_modules/execa": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", - "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "license": "MIT", "dependencies": { - "@sindresorhus/merge-streams": "^4.0.0", - "cross-spawn": "^7.0.6", - "figures": "^6.1.0", - "get-stream": "^9.0.0", - "human-signals": "^8.0.1", - "is-plain-obj": "^4.1.0", - "is-stream": "^4.0.1", - "npm-run-path": "^6.0.0", - "pretty-ms": "^9.2.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^4.0.0", - "yoctocolors": "^2.1.1" - }, - "engines": { - "node": "^18.19.0 || >=20.5.0" + "es-define-property": "^1.0.0" }, "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/imagemin-jpegtran/node_modules/figures": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", - "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "license": "MIT", "dependencies": { - "is-unicode-supported": "^2.0.0" + "dunder-proto": "^1.0.0" }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/imagemin-jpegtran/node_modules/get-stream": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", - "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", - "dependencies": { - "@sec-ant/readable-stream": "^0.4.1", - "is-stream": "^4.0.1" - }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imagemin-jpegtran/node_modules/human-signals": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", - "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/imagemin-jpegtran/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/imagemin-jpegtran/node_modules/npm-run-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", - "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "node_modules/hashery": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz", + "integrity": "sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==", "license": "MIT", "dependencies": { - "path-key": "^4.0.0", - "unicorn-magic": "^0.3.0" + "hookified": "^1.15.0" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=20" } }, - "node_modules/imagemin-jpegtran/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", "license": "MIT", - "engines": { - "node": ">=12" + "dependencies": { + "function-bind": "^1.1.2" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 0.4" } }, - "node_modules/imagemin-jpegtran/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==", - "license": "ISC", + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "dev": true, + "license": "BSD-3-Clause", "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "*" } }, - "node_modules/imagemin-jpegtran/node_modules/strip-final-newline": { + "node_modules/hook-std": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", - "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-4.0.0.tgz", + "integrity": "sha512-IHI4bEVOt3vRUDJ+bFA9VUJlo7SzvFARPNLw75pqSmAOP2HmTWfFJtPvLBrDrlgjEYXY9zs7SFdHPQaJShkSCQ==", + "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/imagemin-jpegtran/node_modules/unicorn-magic": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", - "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "node_modules/hookified": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz", + "integrity": "sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==", + "license": "MIT" + }, + "node_modules/hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", "license": "MIT", "engines": { - "node": ">=18" + "node": ">= 6.0.0" + } + }, + "node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/imagemin-optipng": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/imagemin-optipng/-/imagemin-optipng-8.0.0.tgz", - "integrity": "sha512-CUGfhfwqlPjAC0rm8Fy+R2DJDBGjzy2SkfyT09L8rasnF9jSoHFqJ1xxSZWK6HVPZBMhGPMxCTL70OgTHlLF5A==", + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "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==", "license": "MIT", "dependencies": { - "exec-buffer": "^3.0.0", - "is-png": "^2.0.0", - "optipng-bin": "^7.0.0" + "whatwg-encoding": "^3.1.1" }, "engines": { - "node": ">=10" + "node": ">=18" } }, - "node_modules/imagemin/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==", + "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==", + "license": "MIT" + }, + "node_modules/html-tags": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-5.1.0.tgz", + "integrity": "sha512-n6l5uca7/y5joxZ3LUePhzmBFUJ+U2YWzhMa8XUTecSeSlQiZdF5XAd/Q3/WUl0VsXgUwWi8I7CNIwdI5WN1SQ==", "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20.10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/imagemin/node_modules/globby": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", - "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", + "node_modules/http-proxy-agent": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-9.0.0.tgz", + "integrity": "sha512-FcF8VhXYLQcxWCnt/cCpT2apKsRDUGeVEeMqGu4HSTu29U8Yw0TLOjdYIlDsYk3IkUh+taX4IDWpPcCqKDhCjA==", + "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" + "agent-base": "9.0.0", + "debug": "^4.3.4" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 20" } }, - "node_modules/imagemin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "node_modules/https-proxy-agent": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-9.0.0.tgz", + "integrity": "sha512-/MVmHp58WkOypgFhCLk4fzpPcFQvTJ/e6LBI7irpIO2HfxUbpmYoHF+KzipzJpxxzJu7aJNWQ0xojJ/dzV2G5g==", + "dev": true, "license": "MIT", + "dependencies": { + "agent-base": "9.0.0", + "debug": "^4.3.4" + }, "engines": { - "node": ">= 4" + "node": ">= 20" } }, - "node_modules/imagemin/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==", + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, "license": "MIT", + "bin": { + "husky": "bin.js" + }, "engines": { "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/typicode" } }, - "node_modules/imagemin/node_modules/unicorn-magic": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", - "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "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==", "license": "MIT", "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 4" } }, "node_modules/immutable": { @@ -13798,15 +11708,6 @@ "node": ">=18.20" } }, - "node_modules/import-lazy": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", - "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/import-local": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", @@ -13871,93 +11772,37 @@ "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": "4.1.1", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", - "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", + "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", "dev": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/inquirer/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/inquirer/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "license": "0BSD" - }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "license": "MIT", - "engines": { - "node": ">=10.13.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/into-stream": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-7.0.0.tgz", - "integrity": "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==", - "dev": true, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "license": "MIT", "dependencies": { - "from2": "^2.3.0", - "p-is-promise": "^3.0.0" + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.4" } }, "node_modules/ip-address": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", + "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", "license": "MIT", "engines": { "node": ">= 12" @@ -13972,14 +11817,15 @@ "node": ">= 0.4" } }, - "node_modules/is-arguments": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", - "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -13994,6 +11840,40 @@ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "license": "MIT" }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -14006,6 +11886,22 @@ "node": ">=8" } }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -14019,12 +11915,45 @@ } }, "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==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", "license": "MIT", "dependencies": { - "hasown": "^2.0.2" + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -14057,6 +11986,21 @@ "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", @@ -14113,22 +12057,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-identifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-identifier/-/is-identifier-1.0.1.tgz", - "integrity": "sha512-HQ5v4rEJ7REUV54bCd2l5FaD299SGDEn2UPoVXaTHAyGviLq2menVUD2udi3trQ32uvB6LdAh/0ck2EuizrtpA==", - "license": "MIT", - "dependencies": { - "identifier-regex": "^1.0.0", - "super-regex": "^1.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-in-ssh": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-in-ssh/-/is-in-ssh-1.0.0.tgz", @@ -14159,24 +12087,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-lower-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-1.1.3.tgz", - "integrity": "sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==", + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "license": "MIT", - "dependencies": { - "lower-case": "^1.1.0" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, "engines": { "node": ">= 0.4" }, @@ -14184,12 +12111,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-natural-number": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", - "license": "MIT" - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -14199,62 +12120,49 @@ "node": ">=0.12.0" } }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, "engines": { - "node": ">=8" - } - }, - "node_modules/is-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", - "license": "MIT", + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, "license": "MIT", - "dependencies": { - "is-path-inside": "^2.1.0" - }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "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==", "license": "MIT", - "dependencies": { - "path-is-inside": "^1.0.2" - }, "engines": { - "node": ">=6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -14272,15 +12180,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-png": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-png/-/is-png-2.0.0.tgz", - "integrity": "sha512-4KPGizaVGj2LK7xwJIz8o5B2ubu1D/vcQsgOGFEDlpcvgZHto4gBnyd0ig7Ws+67ixmwKoNmu0hYnpo6AaKb5g==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "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", @@ -14305,15 +12204,33 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -14326,6 +12243,39 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-typed-array": { "version": "1.1.15", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", @@ -14345,6 +12295,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -14353,22 +12304,47 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-upper-case": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-1.1.2.tgz", - "integrity": "sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==", + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", "license": "MIT", "dependencies": { - "upper-case": "^1.1.0" + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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==", + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-wsl": { @@ -14387,9 +12363,9 @@ } }, "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "license": "MIT" }, "node_modules/isexe": { @@ -14398,19 +12374,10 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "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==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/issue-parser": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-7.0.1.tgz", - "integrity": "sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-7.0.2.tgz", + "integrity": "sha512-7atWPjhGEIX3JEtMrOYd8TKzboYlq+5sNbdl9POiLYOI14G5HZiQbZP0Xj5EZdrufQVXfJlpTV0hys0CuxwxZw==", "dev": true, "license": "MIT", "dependencies": { @@ -14450,9 +12417,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -14502,19 +12469,6 @@ "node": ">=8" } }, - "node_modules/isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "license": "MIT", - "dependencies": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - }, - "engines": { - "node": ">= 4" - } - }, "node_modules/java-properties": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", @@ -14525,22 +12479,16 @@ "node": ">= 0.6.0" } }, - "node_modules/javascript-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", - "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", - "license": "MIT" - }, "node_modules/jest": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-30.3.0.tgz", - "integrity": "sha512-AkXIIFcaazymvey2i/+F94XRnM6TsVLZDhBMLsd1Sf/W0wzsvvpjeyUrCZD6HGG4SDYPgDJDBKeiJTBb10WzMg==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.4.2.tgz", + "integrity": "sha512-Yi1jqNC/Oq0N4hBgNH/YvBpP1P57QqundgytzYqy3yqAa7NZPNjSoi4SGbRAXDMdBzNE6xBCi5U7RgfrvMEUVQ==", "license": "MIT", "dependencies": { - "@jest/core": "30.3.0", - "@jest/types": "30.3.0", + "@jest/core": "30.4.2", + "@jest/types": "30.4.1", "import-local": "^3.2.0", - "jest-cli": "30.3.0" + "jest-cli": "30.4.2" }, "bin": { "jest": "bin/jest.js" @@ -14558,13 +12506,13 @@ } }, "node_modules/jest-changed-files": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.3.0.tgz", - "integrity": "sha512-B/7Cny6cV5At6M25EWDgf9S617lHivamL8vl6KEpJqkStauzcG4e+WPfDgMMF+H4FVH4A2PLRyvgDJan4441QA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.4.1.tgz", + "integrity": "sha512-IuctmYrxi21iOSOaIXpJWalHyPAsVv0GeBHKDn8C1CA4W5htHn7INL+wdnL4Bo0+olEndvAFkmb++tIQJG+vvg==", "license": "MIT", "dependencies": { "execa": "^5.1.1", - "jest-util": "30.3.0", + "jest-util": "30.4.1", "p-limit": "^3.1.0" }, "engines": { @@ -14572,28 +12520,28 @@ } }, "node_modules/jest-circus": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.3.0.tgz", - "integrity": "sha512-PyXq5szeSfR/4f1lYqCmmQjh0vqDkURUYi9N6whnHjlRz4IUQfMcXkGLeEoiJtxtyPqgUaUUfyQlApXWBSN1RA==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.4.2.tgz", + "integrity": "sha512-rvHH7VlY6LgbJXJTQ87GW62g1FntOtbhh0zT+v04kC+pgL6aBKyYINXxWukCpj3dcIBMw5/XUbtDS9dU9JTXeQ==", "license": "MIT", "dependencies": { - "@jest/environment": "30.3.0", - "@jest/expect": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/types": "30.3.0", + "@jest/environment": "30.4.1", + "@jest/expect": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", "chalk": "^4.1.2", "co": "^4.6.0", "dedent": "^1.6.0", "is-generator-fn": "^2.1.0", - "jest-each": "30.3.0", - "jest-matcher-utils": "30.3.0", - "jest-message-util": "30.3.0", - "jest-runtime": "30.3.0", - "jest-snapshot": "30.3.0", - "jest-util": "30.3.0", + "jest-each": "30.4.1", + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-runtime": "30.4.2", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", "p-limit": "^3.1.0", - "pretty-format": "30.3.0", + "pretty-format": "30.4.1", "pure-rand": "^7.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" @@ -14602,30 +12550,21 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-circus/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-cli": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.3.0.tgz", - "integrity": "sha512-l6Tqx+j1fDXJEW5bqYykDQQ7mQg+9mhWXtnj+tQZrTWYHyHoi6Be8HPumDSA+UiX2/2buEgjA58iJzdj146uCw==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.4.2.tgz", + "integrity": "sha512-jfA2ocvVHMXS2QijrJ0d31ektP+d/W0T5RpcTX2Pq+3sVqHlsXVCM2+FmwpL+bdY8OfHpIg9xMxLF17Zg0U49Q==", "license": "MIT", "dependencies": { - "@jest/core": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/types": "30.3.0", + "@jest/core": "30.4.2", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", "chalk": "^4.1.2", "exit-x": "^0.2.2", "import-local": "^3.2.0", - "jest-config": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", + "jest-config": "30.4.2", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", "yargs": "^17.7.2" }, "bin": { @@ -14643,33 +12582,91 @@ } } }, + "node_modules/jest-cli/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-cli/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==", + "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/jest-cli/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-cli/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/jest-config": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.3.0.tgz", - "integrity": "sha512-WPMAkMAtNDY9P/oKObtsRG/6KTrhtgPJoBTmk20uDn4Uy6/3EJnnaZJre/FMT1KVRx8cve1r7/FlMIOfRVWL4w==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.4.2.tgz", + "integrity": "sha512-rNHAShJQqQwFNoL0hbf3BphSBOWnpOUAKvidLS/AjNVLPfoj5mSf4jQMfW3cYOs6hXeZC7nF7mDHaBnbxELOzg==", "license": "MIT", "dependencies": { "@babel/core": "^7.27.4", "@jest/get-type": "30.1.0", - "@jest/pattern": "30.0.1", - "@jest/test-sequencer": "30.3.0", - "@jest/types": "30.3.0", - "babel-jest": "30.3.0", + "@jest/pattern": "30.4.0", + "@jest/test-sequencer": "30.4.1", + "@jest/types": "30.4.1", + "babel-jest": "30.4.1", "chalk": "^4.1.2", "ci-info": "^4.2.0", "deepmerge": "^4.3.1", "glob": "^10.5.0", "graceful-fs": "^4.2.11", - "jest-circus": "30.3.0", - "jest-docblock": "30.2.0", - "jest-environment-node": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.3.0", - "jest-runner": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", + "jest-circus": "30.4.2", + "jest-docblock": "30.4.0", + "jest-environment-node": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-runner": "30.4.2", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", "parse-json": "^5.2.0", - "pretty-format": "30.3.0", + "pretty-format": "30.4.1", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -14693,34 +12690,25 @@ } } }, - "node_modules/jest-config/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-diff": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", - "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", + "integrity": "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==", "license": "MIT", "dependencies": { - "@jest/diff-sequences": "30.3.0", + "@jest/diff-sequences": "30.4.0", "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "pretty-format": "30.3.0" + "pretty-format": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-docblock": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz", - "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.4.0.tgz", + "integrity": "sha512-ZPMabUZCx5MpbZ2eBYSvZ0J8fvo3dR9oM+eeUpb3aKNQFuS2tu3Duw1TNlMoP8k3WQgKGJuhcMFvwcVuq6T7oA==", "license": "MIT", "dependencies": { "detect-newline": "^3.1.0" @@ -14730,29 +12718,29 @@ } }, "node_modules/jest-each": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.3.0.tgz", - "integrity": "sha512-V8eMndg/aZ+3LnCJgSm13IxS5XSBM22QSZc9BtPK8Dek6pm+hfUNfwBdvsB3d342bo1q7wnSkC38zjX259qZNA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.4.1.tgz", + "integrity": "sha512-/8MJbH6fuj48TstjrMf+u/pd06Qezz5xOXvZA6442heNOWr8bdeoGZX2d9fCn028CoMgYmroH9//zky5GfyYmA==", "license": "MIT", "dependencies": { "@jest/get-type": "30.1.0", - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "chalk": "^4.1.2", - "jest-util": "30.3.0", - "pretty-format": "30.3.0" + "jest-util": "30.4.1", + "pretty-format": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-environment-jsdom": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-30.3.0.tgz", - "integrity": "sha512-RLEOJy6ip1lpw0yqJ8tB3i88FC7VBz7i00Zvl2qF71IdxjS98gC9/0SPWYIBVXHm5hgCYK0PAlSlnHGGy9RoMg==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-30.4.1.tgz", + "integrity": "sha512-o3nfaN4zej7qgk2X0j8Jhq/S9nAVKs2xK3QeQxeHVvpkEPxaA1yxDGydR+iVI7zPy7Cp62Aq2h3Ja46QvfWHGA==", "license": "MIT", "dependencies": { - "@jest/environment": "30.3.0", - "@jest/environment-jsdom-abstract": "30.3.0", + "@jest/environment": "30.4.1", + "@jest/environment-jsdom-abstract": "30.4.1", "jsdom": "^26.1.0" }, "engines": { @@ -14768,37 +12756,37 @@ } }, "node_modules/jest-environment-node": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.3.0.tgz", - "integrity": "sha512-4i6HItw/JSiJVsC5q0hnKIe/hbYfZLVG9YJ/0pU9Hz2n/9qZe3Rhn5s5CUZA5ORZlcdT/vmAXRMyONXJwPrmYQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.4.1.tgz", + "integrity": "sha512-4FZYVOk85hz2AyT6BbarKy9u37g6DbrDyCdFhsnDdXqyrueYQvB+0zO4f/kqLCRD0BsPRXPMNJeQwihKZV8naw==", "license": "MIT", "dependencies": { - "@jest/environment": "30.3.0", - "@jest/fake-timers": "30.3.0", - "@jest/types": "30.3.0", + "@jest/environment": "30.4.1", + "@jest/fake-timers": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "jest-mock": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0" + "jest-mock": "30.4.1", + "jest-util": "30.4.1", + "jest-validate": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-haste-map": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.3.0.tgz", - "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", + "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", "license": "MIT", "dependencies": { - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@types/node": "*", "anymatch": "^3.1.3", "fb-watchman": "^2.0.2", "graceful-fs": "^4.2.11", - "jest-regex-util": "30.0.1", - "jest-util": "30.3.0", - "jest-worker": "30.3.0", + "jest-regex-util": "30.4.0", + "jest-util": "30.4.1", + "jest-worker": "30.4.1", "picomatch": "^4.0.3", "walker": "^1.0.8" }, @@ -14822,46 +12810,47 @@ } }, "node_modules/jest-leak-detector": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.3.0.tgz", - "integrity": "sha512-cuKmUUGIjfXZAiGJ7TbEMx0bcqNdPPI6P1V+7aF+m/FUJqFDxkFR4JqkTu8ZOiU5AaX/x0hZ20KaaIPXQzbMGQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.4.1.tgz", + "integrity": "sha512-IpmyiioeHxiWDhesHnUFmOxcTzwCwKpgACgWajtAP+nYQXiY7DakTxB6Bx9JFiRMljr0AX1PvnQdaU1KFoz6NQ==", "license": "MIT", "dependencies": { "@jest/get-type": "30.1.0", - "pretty-format": "30.3.0" + "pretty-format": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.3.0.tgz", - "integrity": "sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.4.1.tgz", + "integrity": "sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==", "license": "MIT", "dependencies": { "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "jest-diff": "30.3.0", - "pretty-format": "30.3.0" + "jest-diff": "30.4.1", + "pretty-format": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-message-util": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.3.0.tgz", - "integrity": "sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", + "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", + "jest-util": "30.4.1", "picomatch": "^4.0.3", - "pretty-format": "30.3.0", + "pretty-format": "30.4.1", "slash": "^3.0.0", "stack-utils": "^2.0.6" }, @@ -14881,24 +12870,15 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/jest-message-util/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-mock": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.3.0.tgz", - "integrity": "sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", + "integrity": "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==", "license": "MIT", "dependencies": { - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@types/node": "*", - "jest-util": "30.3.0" + "jest-util": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -14922,26 +12902,26 @@ } }, "node_modules/jest-regex-util": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", - "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", + "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", "license": "MIT", "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-resolve": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.3.0.tgz", - "integrity": "sha512-NRtTAHQlpd15F9rUR36jqwelbrDV/dY4vzNte3S2kxCKUJRYNd5/6nTSbYiak1VX5g8IoFF23Uj5TURkUW8O5g==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.4.1.tgz", + "integrity": "sha512-Zry8Yq/yJcNAZ7dJ5F2heic8AheXvbFZ7XI5V+h28nrYZ7Qoyy4dItq8OodjnYD270mvX+ZudmrNV9cysqhW5Q==", "license": "MIT", "dependencies": { "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", + "jest-haste-map": "30.4.1", "jest-pnp-resolver": "^1.2.3", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", "slash": "^3.0.0", "unrs-resolver": "^1.7.11" }, @@ -14950,53 +12930,44 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.3.0.tgz", - "integrity": "sha512-9ev8s3YN6Hsyz9LV75XUwkCVFlwPbaFn6Wp75qnI0wzAINYWY8Fb3+6y59Rwd3QaS3kKXffHXsZMziMavfz/nw==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.4.2.tgz", + "integrity": "sha512-gDiVh1I+GxYzz9oXlyw+1wv6VOYX1WYxMOfjsA3iGKePV2oxmbHhwxfkALxNxYy1ciw6APWwkW2zZONwP97aEQ==", "license": "MIT", "dependencies": { - "jest-regex-util": "30.0.1", - "jest-snapshot": "30.3.0" + "jest-regex-util": "30.4.0", + "jest-snapshot": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-runner": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.3.0.tgz", - "integrity": "sha512-gDv6C9LGKWDPLia9TSzZwf4h3kMQCqyTpq+95PODnTRDO0g9os48XIYYkS6D236vjpBir2fF63YmJFtqkS5Duw==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.4.2.tgz", + "integrity": "sha512-2dw0PslVYXxffXGpLo+Ejad+KcI1Qkjn7f4X4619gf21oCUmL+SPfjqIa/losUem3yEOvfNZe/F1HWUcNpODcg==", "license": "MIT", "dependencies": { - "@jest/console": "30.3.0", - "@jest/environment": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", + "@jest/console": "30.4.1", + "@jest/environment": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", "chalk": "^4.1.2", "emittery": "^0.13.1", "exit-x": "^0.2.2", "graceful-fs": "^4.2.11", - "jest-docblock": "30.2.0", - "jest-environment-node": "30.3.0", - "jest-haste-map": "30.3.0", - "jest-leak-detector": "30.3.0", - "jest-message-util": "30.3.0", - "jest-resolve": "30.3.0", - "jest-runtime": "30.3.0", - "jest-util": "30.3.0", - "jest-watcher": "30.3.0", - "jest-worker": "30.3.0", + "jest-docblock": "30.4.0", + "jest-environment-node": "30.4.1", + "jest-haste-map": "30.4.1", + "jest-leak-detector": "30.4.1", + "jest-message-util": "30.4.1", + "jest-resolve": "30.4.1", + "jest-runtime": "30.4.2", + "jest-util": "30.4.1", + "jest-watcher": "30.4.1", + "jest-worker": "30.4.1", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -15005,31 +12976,31 @@ } }, "node_modules/jest-runtime": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.3.0.tgz", - "integrity": "sha512-CgC+hIBJbuh78HEffkhNKcbXAytQViplcl8xupqeIWyKQF50kCQA8J7GeJCkjisC6hpnC9Muf8jV5RdtdFbGng==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.4.2.tgz", + "integrity": "sha512-3/5e8iPz2k/VLqlr8DgTftYyLUv8Su3FkCAO2/Od81UsUTpSxOrS6O5x5KkoQwyUjmpYyDJKeyAvg2T2nvpNkQ==", "license": "MIT", "dependencies": { - "@jest/environment": "30.3.0", - "@jest/fake-timers": "30.3.0", - "@jest/globals": "30.3.0", + "@jest/environment": "30.4.1", + "@jest/fake-timers": "30.4.1", + "@jest/globals": "30.4.1", "@jest/source-map": "30.0.1", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", "chalk": "^4.1.2", "cjs-module-lexer": "^2.1.0", "collect-v8-coverage": "^1.0.2", "glob": "^10.5.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", - "jest-message-util": "30.3.0", - "jest-mock": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.3.0", - "jest-snapshot": "30.3.0", - "jest-util": "30.3.0", + "jest-haste-map": "30.4.1", + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -15037,25 +13008,10 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runtime/node_modules/cjs-module-lexer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", - "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", - "license": "MIT" - }, - "node_modules/jest-runtime/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-snapshot": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.3.0.tgz", - "integrity": "sha512-f14c7atpb4O2DeNhwcvS810Y63wEn8O1HqK/luJ4F6M4NjvxmAKQwBUWjbExUtMxWJQ0wVgmCKymeJK6NZMnfQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.4.1.tgz", + "integrity": "sha512-tEOkkfOMppUyeiHwjZswOQ3lcnoTnws/q5FnGIaeIh/jmoU0ZlgMYRR8sTlTj+nNGCoJ0RDq6SfxGxCsyMTPmw==", "license": "MIT", "dependencies": { "@babel/core": "^7.27.4", @@ -15063,20 +13019,20 @@ "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.3.0", + "@jest/expect-utils": "30.4.1", "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", + "@jest/snapshot-utils": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "babel-preset-current-node-syntax": "^1.2.0", "chalk": "^4.1.2", - "expect": "30.3.0", + "expect": "30.4.1", "graceful-fs": "^4.2.11", - "jest-diff": "30.3.0", - "jest-matcher-utils": "30.3.0", - "jest-message-util": "30.3.0", - "jest-util": "30.3.0", - "pretty-format": "30.3.0", + "jest-diff": "30.4.1", + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", + "pretty-format": "30.4.1", "semver": "^7.7.2", "synckit": "^0.11.8" }, @@ -15085,9 +13041,9 @@ } }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -15097,12 +13053,12 @@ } }, "node_modules/jest-util": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.3.0.tgz", - "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", + "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", "license": "MIT", "dependencies": { - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -15126,17 +13082,17 @@ } }, "node_modules/jest-validate": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.3.0.tgz", - "integrity": "sha512-I/xzC8h5G+SHCb2P2gWkJYrNiTbeL47KvKeW5EzplkyxzBRBw1ssSHlI/jXec0ukH2q7x2zAWQm7015iusg62Q==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.4.1.tgz", + "integrity": "sha512-PDWi4SOwLnwqNDfHZjOcsEFyZ4fc/2W2gVL3DEoyqnB6jCQMLRtfBong8s6omIw3lI0HWOus12xfnFmQtjW3fw==", "license": "MIT", "dependencies": { "@jest/get-type": "30.1.0", - "@jest/types": "30.3.0", + "@jest/types": "30.4.1", "camelcase": "^6.3.0", "chalk": "^4.1.2", "leven": "^3.1.0", - "pretty-format": "30.3.0" + "pretty-format": "30.4.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -15155,18 +13111,18 @@ } }, "node_modules/jest-watcher": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.3.0.tgz", - "integrity": "sha512-PJ1d9ThtTR8aMiBWUdcownq9mDdLXsQzJayTk4kmaBRHKvwNQn+ANveuhEBUyNI2hR1TVhvQ8D5kHubbzBHR/w==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.4.1.tgz", + "integrity": "sha512-/l9UonmvCwjHH7d2h3iAwIloLc1H0S8mJZ/LNK3i86hqwPAz8otUJjP9MfYtz9Tt77Su5FD2xGjZn8d31IZHlw==", "license": "MIT", "dependencies": { - "@jest/test-result": "30.3.0", - "@jest/types": "30.3.0", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "emittery": "^0.13.1", - "jest-util": "30.3.0", + "jest-util": "30.4.1", "string-length": "^4.0.2" }, "engines": { @@ -15174,14 +13130,14 @@ } }, "node_modules/jest-worker": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.3.0.tgz", - "integrity": "sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", + "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", "license": "MIT", "dependencies": { "@types/node": "*", "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.3.0", + "jest-util": "30.4.1", "merge-stream": "^2.0.0", "supports-color": "^8.1.1" }, @@ -15206,105 +13162,30 @@ }, "node_modules/jiti": { "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/jpegtran-bin": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/jpegtran-bin/-/jpegtran-bin-7.0.0.tgz", - "integrity": "sha512-8ecI4vXIV7eI2+nzRQsHAVaQVBGDotUY76CJZhlYaBAljBnK/509+sGGCs8eJyiS5N4tOcYZS+8Q4KgzorqlBA==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "bin-build": "^3.0.0", - "bin-wrapper": "^4.0.0" - }, - "bin": { - "jpegtran": "cli.js" - }, - "engines": { - "node": "^14.13.1 || >=16.0.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==", - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/js-yaml-loader": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/js-yaml-loader/-/js-yaml-loader-1.2.2.tgz", - "integrity": "sha512-H+NeuNrG6uOs/WMjna2SjkaCw13rMWiT/D7l9+9x5n8aq88BDsh2sRmdfxckWPIHtViYHWRG6XiCKYvS1dfyLg==", - "license": "MIT", - "dependencies": { - "js-yaml": "^3.13.1", - "loader-utils": "^1.2.3", - "un-eval": "^1.2.0" - } - }, - "node_modules/js-yaml-loader/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/js-yaml-loader/node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/js-yaml-loader/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "devOptional": true, "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, "bin": { - "json5": "lib/cli.js" + "jiti": "lib/jiti-cli.mjs" } }, - "node_modules/js-yaml-loader/node_modules/loader-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "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==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "license": "MIT", "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" + "argparse": "^2.0.1" }, - "engines": { - "node": ">=4.0.0" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, "node_modules/jsdom": { @@ -15346,6 +13227,41 @@ } } }, + "node_modules/jsdom/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==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/jsdom/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==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/jsdom/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==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -15364,21 +13280,6 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "license": "MIT" }, - "node_modules/json-fixer": { - "version": "1.6.15", - "resolved": "https://registry.npmjs.org/json-fixer/-/json-fixer-1.6.15.tgz", - "integrity": "sha512-TuDuZ5KrgyjoCIppdPXBMqiGfota55+odM+j2cQ5rt/XKyKmqGB3Whz1F8SN8+60yYGy/Nu5lbRZ+rx8kBIvBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.18.9", - "chalk": "^4.1.2", - "pegjs": "^0.10.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -15424,9 +13325,9 @@ } }, "node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", "license": "MIT", "dependencies": { "universalify": "^2.0.0" @@ -15435,18 +13336,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/junk": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz", - "integrity": "sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==", - "license": "MIT", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -15509,37 +13398,28 @@ "license": "MIT" }, "node_modules/lint-staged": { - "version": "16.4.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.4.0.tgz", - "integrity": "sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw==", + "version": "17.0.5", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-17.0.5.tgz", + "integrity": "sha512-d12yC+/e8RhBjZtaxZn71FyrgU/P5e+uAPifhCLwdosQZP/zamSdKRWDC30ocVIbzDKiFG1McHc/LUgB92GIPw==", "dev": true, "license": "MIT", "dependencies": { - "commander": "^14.0.3", - "listr2": "^9.0.5", - "picomatch": "^4.0.3", + "listr2": "^10.2.1", + "picomatch": "^4.0.4", "string-argv": "^0.3.2", - "tinyexec": "^1.0.4", - "yaml": "^2.8.2" + "tinyexec": "^1.1.2" }, "bin": { "lint-staged": "bin/lint-staged.js" }, "engines": { - "node": ">=20.17" + "node": ">=22.22.1" }, "funding": { "url": "https://opencollective.com/lint-staged" - } - }, - "node_modules/lint-staged/node_modules/commander": { - "version": "14.0.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", - "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=20" + }, + "optionalDependencies": { + "yaml": "^2.8.4" } }, "node_modules/lint-staged/node_modules/picomatch": { @@ -15556,21 +13436,20 @@ } }, "node_modules/listr2": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", - "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-10.2.1.tgz", + "integrity": "sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q==", "dev": true, "license": "MIT", "dependencies": { - "cli-truncate": "^5.0.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", + "cli-truncate": "^5.2.0", + "eventemitter3": "^5.0.4", "log-update": "^6.1.0", "rfdc": "^1.4.1", - "wrap-ansi": "^9.0.0" + "wrap-ansi": "^10.0.0" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.13.0" } }, "node_modules/load-json-file": { @@ -15623,33 +13502,6 @@ "node": ">=4" } }, - "node_modules/loader-runner": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", - "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", - "license": "MIT", - "engines": { - "node": ">=6.11.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -15666,12 +13518,12 @@ } }, "node_modules/locutus": { - "version": "2.0.39", - "resolved": "https://registry.npmjs.org/locutus/-/locutus-2.0.39.tgz", - "integrity": "sha512-v2iub44UtGpbIv+pFkkYhZ+JsbIM0bJsQcQ1+VayUNGVA/YhM8+CkBiRACcpuuE9Q0xI1pgNzGNwzZDCp1MCww==", + "version": "3.0.36", + "resolved": "https://registry.npmjs.org/locutus/-/locutus-3.0.36.tgz", + "integrity": "sha512-ilsz33lqEd+KerV9JnSHM9EApVYOZ86/JTGKyafmWvhTFtjYauzT1WmZgdJ4JBGR3dY0N0PTfIq2uLvazw5QsQ==", "license": "MIT", "engines": { - "node": ">= 10", + "node": ">= 22", "yarn": ">= 1" } }, @@ -15685,12 +13537,6 @@ "version": "4.18.1", "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz", "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==", - "license": "MIT" - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "dev": true, "license": "MIT" }, @@ -15728,32 +13574,10 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.mergewith": { + "node_modules/lodash.merge": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.snakecase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", - "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.startcase": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", - "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", - "dev": true, + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "license": "MIT" }, "node_modules/lodash.truncate": { @@ -15769,13 +13593,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash.upperfirst": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", - "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", - "dev": true, - "license": "MIT" - }, "node_modules/log-update": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", @@ -15841,6 +13658,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, "node_modules/log-update/node_modules/onetime": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", @@ -15904,6 +13728,24 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/log-update/node_modules/strip-ansi": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", @@ -15920,36 +13762,30 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/loupe": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", "license": "MIT" }, - "node_modules/lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", - "license": "MIT" - }, - "node_modules/lower-case-first": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-1.0.2.tgz", - "integrity": "sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA==", - "license": "MIT", - "dependencies": { - "lower-case": "^1.1.2" - } - }, - "node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -15964,6 +13800,7 @@ "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "license": "MIT", + "peer": true, "bin": { "lz-string": "bin/bin.js" } @@ -15981,6 +13818,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/make-asynchronous/-/make-asynchronous-1.1.0.tgz", "integrity": "sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg==", + "dev": true, "license": "MIT", "dependencies": { "p-event": "^6.0.0", @@ -15994,37 +13832,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-asynchronous/node_modules/p-event": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-6.0.1.tgz", - "integrity": "sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==", - "license": "MIT", - "dependencies": { - "p-timeout": "^6.1.2" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-asynchronous/node_modules/p-timeout": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", - "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/make-asynchronous/node_modules/type-fest": { "version": "4.41.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=16" @@ -16049,9 +13861,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -16158,18 +13970,6 @@ "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", "license": "CC0-1.0" }, - "node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", - "license": "Unlicense", - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/meow": { "version": "13.2.0", "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", @@ -16227,36 +14027,6 @@ "node": ">=16" } }, - "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -16266,79 +14036,38 @@ "node": ">=6" } }, - "node_modules/mimic-function": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", - "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/mini-css-extract-plugin": { - "version": "2.10.2", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.10.2.tgz", - "integrity": "sha512-AOSS0IdEB95ayVkxn5oGzNQwqAi2J0Jb/kKm43t7H73s8+f5873g0yuj0PNvK4dO75mu5DHg4nlgp4k6Kga8eg==", + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, "license": "MIT", - "dependencies": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - }, "engines": { - "node": ">= 12.13.0" + "node": ">=18" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mini-svg-data-uri": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", - "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "license": "MIT", - "bin": { - "mini-svg-data-uri": "cli.js" + "engines": { + "node": ">=4" } }, "node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "license": "BlueOak-1.0.0", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "license": "ISC", "dependencies": { - "brace-expansion": "^5.0.5" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "*" } }, "node_modules/minimist": { @@ -16365,21 +14094,6 @@ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", "license": "MIT" }, - "node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "license": "MIT", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -16395,13 +14109,6 @@ "mustache": "bin/mustache" } }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true, - "license": "ISC" - }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -16415,9 +14122,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", "funding": [ { "type": "github", @@ -16457,6 +14164,7 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, "license": "MIT" }, "node_modules/nerf-dart": { @@ -16475,27 +14183,6 @@ "node": ">= 0.4.0" } }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "license": "MIT" - }, - "node_modules/no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "license": "MIT", - "dependencies": { - "lower-case": "^1.1.1" - } - }, - "node_modules/node-abort-controller": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", - "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", - "license": "MIT" - }, "node_modules/node-addon-api": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", @@ -16519,63 +14206,22 @@ "node": ">=18" } }, - "node_modules/node-emoji/node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, + "node_modules/node-exports-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", + "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", "license": "MIT", "dependencies": { - "whatwg-url": "^5.0.0" + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" }, "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/node-int64": { @@ -16585,57 +14231,12 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.37", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz", - "integrity": "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==", - "license": "MIT" - }, - "node_modules/node-sass-glob-importer": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/node-sass-glob-importer/-/node-sass-glob-importer-5.3.3.tgz", - "integrity": "sha512-888UlmX8fiGMCQ+8/w6e3VjPlmuIPBQfbupAGnG0kfQbpto9OtofULN1xCmlvKD5e38Sz+PpETXqgogheqAMqQ==", - "license": "MIT", - "dependencies": { - "node-sass-magic-importer": "^5.3.3" - }, - "engines": { - "node": ">=6.11.1", - "npm": ">=3.0.0" - } - }, - "node_modules/node-sass-magic-importer": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/node-sass-magic-importer/-/node-sass-magic-importer-5.3.3.tgz", - "integrity": "sha512-xB4yH7laj00SBIZO9Hwke3XDSqMcz+6IM7TgcxU9Ri6m6Pn8MBWwgG5HLmgZkQX3W2osUhx+k7WSOzzunuTKVw==", - "license": "MIT", - "dependencies": { - "css-node-extract": "^2.1.3", - "css-selector-extract": "^3.3.6", - "findup-sync": "^4.0.0", - "glob": "^7.1.6", - "object-hash": "^2.0.3", - "postcss-scss": "^3.0.2", - "resolve": "^1.17.0" - }, - "engines": { - "node": ">=6.11.1", - "npm": ">=3.0.0" - } - }, - "node_modules/node-sass-magic-importer/node_modules/postcss-scss": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-3.0.5.tgz", - "integrity": "sha512-3e0qYk87eczfzg5P73ZVuuxEGCBfatRhPze6KrSaIbEKVtmnFI1RYp1Fv+AyZi+w8kcNRSPeNX6ap4b65zEkiA==", + "version": "2.0.46", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.46.tgz", + "integrity": "sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==", "license": "MIT", - "dependencies": { - "postcss": "^8.2.7" - }, "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" + "node": ">=18" } }, "node_modules/node.extend": { @@ -16667,9 +14268,9 @@ } }, "node_modules/normalize-package-data/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", "dev": true, "license": "ISC", "bin": { @@ -16689,9 +14290,9 @@ } }, "node_modules/normalize-url": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-9.0.0.tgz", - "integrity": "sha512-z9nC87iaZXXySbWWtTHfCFJyFvKaUAW6lODhikG7ILSbVgmwuFjUqkgnheHvAUcGedO29e2QGBRXMUD64aurqQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-9.0.1.tgz", + "integrity": "sha512-ARftfC5HdUNu9jJeL8pHj8debUIHA2b91FizCoMzY4lG6dDX13jdvTK0TBe24IBDRf2HvJSzzwEPvmbkQWHRSg==", "dev": true, "license": "MIT", "engines": { @@ -16708,9 +14309,9 @@ "license": "MIT" }, "node_modules/npm": { - "version": "11.12.1", - "resolved": "https://registry.npmjs.org/npm/-/npm-11.12.1.tgz", - "integrity": "sha512-zcoUuF1kezGSAo0CqtvoLXX3mkRqzuqYdL6Y5tdo8g69NVV3CkjQ6ZBhBgB4d7vGkPcV6TcvLi3GRKPDFX+xTA==", + "version": "11.15.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-11.15.0.tgz", + "integrity": "sha512-+k0tk7lRnpMUPnC7kTuU/yrV/mnFoPhJQ75VfLtZ6fwbzOVXaPsTE/Il9Pn1DHi482byMyqkHv/XsQ76mNjXLw==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -16789,8 +14390,8 @@ ], "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^9.4.2", - "@npmcli/config": "^10.8.1", + "@npmcli/arborist": "^9.6.0", + "@npmcli/config": "^10.9.1", "@npmcli/fs": "^5.0.0", "@npmcli/map-workspaces": "^5.0.3", "@npmcli/metavuln-calculator": "^9.0.3", @@ -16808,27 +14409,27 @@ "fs-minipass": "^3.0.3", "glob": "^13.0.6", "graceful-fs": "^4.2.11", - "hosted-git-info": "^9.0.2", + "hosted-git-info": "^9.0.3", "ini": "^6.0.0", "init-package-json": "^8.2.5", - "is-cidr": "^6.0.3", + "is-cidr": "^6.0.4", "json-parse-even-better-errors": "^5.0.0", "libnpmaccess": "^10.0.3", - "libnpmdiff": "^8.1.5", - "libnpmexec": "^10.2.5", - "libnpmfund": "^7.0.19", + "libnpmdiff": "^8.1.8", + "libnpmexec": "^10.2.8", + "libnpmfund": "^7.0.22", "libnpmorg": "^8.0.1", - "libnpmpack": "^9.1.5", - "libnpmpublish": "^11.1.3", + "libnpmpack": "^9.1.8", + "libnpmpublish": "^11.2.0", "libnpmsearch": "^9.0.1", "libnpmteam": "^8.0.2", "libnpmversion": "^8.0.3", "make-fetch-happen": "^15.0.5", - "minimatch": "^10.2.4", + "minimatch": "^10.2.5", "minipass": "^7.1.3", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", - "node-gyp": "^12.2.0", + "node-gyp": "^12.3.0", "nopt": "^9.0.0", "npm-audit-report": "^7.0.0", "npm-install-checks": "^8.0.0", @@ -16843,11 +14444,11 @@ "proc-log": "^6.1.0", "qrcode-terminal": "^0.12.0", "read": "^5.0.1", - "semver": "^7.7.4", + "semver": "^7.8.0", "spdx-expression-parse": "^4.0.0", "ssri": "^13.0.1", "supports-color": "^10.2.2", - "tar": "^7.5.11", + "tar": "^7.5.15", "text-table": "~0.2.0", "tiny-relative-date": "^2.0.2", "treeverse": "^3.0.0", @@ -16862,28 +14463,6 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/npm-conf": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", - "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", - "license": "MIT", - "dependencies": { - "config-chain": "^1.1.11", - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-conf/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -16940,7 +14519,7 @@ } }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "9.4.2", + "version": "9.6.0", "dev": true, "inBundle": true, "license": "ISC", @@ -16988,7 +14567,7 @@ } }, "node_modules/npm/node_modules/@npmcli/config": { - "version": "10.8.1", + "version": "10.9.1", "dev": true, "inBundle": true, "license": "ISC", @@ -17191,7 +14770,7 @@ } }, "node_modules/npm/node_modules/@sigstore/protobuf-specs": { - "version": "0.5.0", + "version": "0.5.1", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -17305,7 +14884,7 @@ } }, "node_modules/npm/node_modules/bin-links": { - "version": "6.0.0", + "version": "6.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -17333,7 +14912,7 @@ } }, "node_modules/npm/node_modules/brace-expansion": { - "version": "5.0.4", + "version": "5.0.6", "dev": true, "inBundle": true, "license": "MIT", @@ -17402,7 +14981,7 @@ } }, "node_modules/npm/node_modules/cidr-regex": { - "version": "5.0.3", + "version": "5.0.5", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -17458,7 +15037,7 @@ } }, "node_modules/npm/node_modules/diff": { - "version": "8.0.3", + "version": "8.0.4", "dev": true, "inBundle": true, "license": "BSD-3-Clause", @@ -17526,7 +15105,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/hosted-git-info": { - "version": "9.0.2", + "version": "9.0.3", "dev": true, "inBundle": true, "license": "ISC", @@ -17625,7 +15204,7 @@ } }, "node_modules/npm/node_modules/ip-address": { - "version": "10.1.0", + "version": "10.2.0", "dev": true, "inBundle": true, "license": "MIT", @@ -17634,12 +15213,12 @@ } }, "node_modules/npm/node_modules/is-cidr": { - "version": "6.0.3", + "version": "6.0.4", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { - "cidr-regex": "^5.0.1" + "cidr-regex": "^5.0.4" }, "engines": { "node": ">=20" @@ -17707,12 +15286,12 @@ } }, "node_modules/npm/node_modules/libnpmdiff": { - "version": "8.1.5", + "version": "8.1.8", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^9.4.2", + "@npmcli/arborist": "^9.6.0", "@npmcli/installed-package-contents": "^4.0.0", "binary-extensions": "^3.0.0", "diff": "^8.0.2", @@ -17726,13 +15305,13 @@ } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "10.2.5", + "version": "10.2.8", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@gar/promise-retry": "^1.0.0", - "@npmcli/arborist": "^9.4.2", + "@npmcli/arborist": "^9.6.0", "@npmcli/package-json": "^7.0.0", "@npmcli/run-script": "^10.0.0", "ci-info": "^4.0.0", @@ -17749,12 +15328,12 @@ } }, "node_modules/npm/node_modules/libnpmfund": { - "version": "7.0.19", + "version": "7.0.22", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^9.4.2" + "@npmcli/arborist": "^9.6.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" @@ -17774,12 +15353,12 @@ } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "9.1.5", + "version": "9.1.8", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^9.4.2", + "@npmcli/arborist": "^9.6.0", "@npmcli/run-script": "^10.0.0", "npm-package-arg": "^13.0.0", "pacote": "^21.0.2" @@ -17789,7 +15368,7 @@ } }, "node_modules/npm/node_modules/libnpmpublish": { - "version": "11.1.3", + "version": "11.2.0", "dev": true, "inBundle": true, "license": "ISC", @@ -17849,7 +15428,7 @@ } }, "node_modules/npm/node_modules/lru-cache": { - "version": "11.2.7", + "version": "11.5.0", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", @@ -17881,12 +15460,12 @@ } }, "node_modules/npm/node_modules/minimatch": { - "version": "10.2.4", + "version": "10.2.5", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -17934,35 +15513,17 @@ } }, "node_modules/npm/node_modules/minipass-flush": { - "version": "1.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", + "version": "1.0.6", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "yallist": "^4.0.0" + "minipass": "^7.1.3" }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/npm/node_modules/minipass-flush/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/npm/node_modules/minipass-pipeline": { "version": "1.2.4", "dev": true, @@ -18042,7 +15603,7 @@ } }, "node_modules/npm/node_modules/node-gyp": { - "version": "12.2.0", + "version": "12.3.0", "dev": true, "inBundle": true, "license": "MIT", @@ -18050,12 +15611,12 @@ "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", - "make-fetch-happen": "^15.0.0", "nopt": "^9.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5", "tar": "^7.5.4", "tinyglobby": "^0.2.12", + "undici": "^6.25.0", "which": "^6.0.0" }, "bin": { @@ -18377,7 +15938,7 @@ "optional": true }, "node_modules/npm/node_modules/semver": { - "version": "7.7.4", + "version": "7.8.0", "dev": true, "inBundle": true, "license": "ISC", @@ -18428,12 +15989,12 @@ } }, "node_modules/npm/node_modules/socks": { - "version": "2.8.7", + "version": "2.8.9", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ip-address": "^10.0.1", + "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" }, "engines": { @@ -18502,7 +16063,7 @@ } }, "node_modules/npm/node_modules/tar": { - "version": "7.5.11", + "version": "7.5.15", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", @@ -18530,13 +16091,13 @@ "license": "MIT" }, "node_modules/npm/node_modules/tinyglobby": { - "version": "0.2.15", + "version": "0.2.16", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -18563,7 +16124,7 @@ } }, "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", + "version": "4.0.4", "dev": true, "inBundle": true, "license": "MIT", @@ -18597,6 +16158,15 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/npm/node_modules/undici": { + "version": "6.25.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, "node_modules/npm/node_modules/util-deprecate": { "version": "1.0.2", "dev": true, @@ -18679,20 +16249,12 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -18705,14 +16267,60 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "license": "MIT", "dependencies": { "call-bind": "^1.0.7", - "define-properties": "^1.2.1" + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -18721,27 +16329,30 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, "engines": { "node": ">= 0.4" } }, - "node_modules/object.assign": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0", - "has-symbols": "^1.1.0", - "object-keys": "^1.1.1" + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -18815,24 +16426,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/open-cli/node_modules/file-type": { - "version": "21.3.4", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.4.tgz", - "integrity": "sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==", - "license": "MIT", - "dependencies": { - "@tokenizer/inflate": "^0.4.1", - "strtok3": "^10.3.4", - "token-types": "^6.1.1", - "uint8array-extras": "^1.4.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sindresorhus/file-type?sponsor=1" - } - }, "node_modules/open-cli/node_modules/meow": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/meow/-/meow-14.1.0.tgz", @@ -18845,22 +16438,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/open-cli/node_modules/strtok3": { - "version": "10.3.5", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.5.tgz", - "integrity": "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==", - "license": "MIT", - "dependencies": { - "@tokenizer/token": "^0.3.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -18878,111 +16455,89 @@ "node": ">= 0.8.0" } }, - "node_modules/optipng-bin": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/optipng-bin/-/optipng-bin-7.0.1.tgz", - "integrity": "sha512-W99mpdW7Nt2PpFiaO+74pkht7KEqkXkeRomdWXfEz3SALZ6hns81y/pm1dsGZ6ItUIfchiNIP6ORDr1zETU1jA==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "bin-build": "^3.0.0", - "bin-wrapper": "^4.0.0" - }, - "bin": { - "optipng": "cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/os-filter-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz", - "integrity": "sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg==", - "license": "MIT", - "dependencies": { - "arch": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ow": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ow/-/ow-2.0.0.tgz", - "integrity": "sha512-ESUigmGrdhUZ2nQSFNkeKSl6ZRPupXzprMs3yF9DYlNVpJ8XAjM/fI9RUZxA7PI1K9HQDCCvBo1jr/GEIo9joQ==", + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", "license": "MIT", "dependencies": { - "@sindresorhus/is": "^6.3.0", - "callsites": "^4.1.0", - "dot-prop": "^8.0.2", - "environment": "^1.0.0", - "fast-equals": "^5.0.1", - "is-identifier": "^1.0.0" - }, - "engines": { - "node": ">=18" + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ow/node_modules/callsites": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-4.2.0.tgz", - "integrity": "sha512-kfzR4zzQtAE9PC7CzZsjl3aBNbXWuXiSeOCdLcPpBfGW8YuCqQHcRPFDbr/BPVmd3EEPVpuFzLyuT/cUhPr4OQ==", - "license": "MIT", "engines": { - "node": ">=12.20" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ow/node_modules/dot-prop": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-8.0.2.tgz", - "integrity": "sha512-xaBe6ZT4DHPkg0k4Ytbvn5xoxgpG0jOS1dYxSOwAHPuNLjP3/OzN0gH55SrLqpx8cBfSaVt91lXYkApjb+nYdQ==", + "node_modules/oxc-parser": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.127.0.tgz", + "integrity": "sha512-bkgD4qHlN7WxLdX8bLXdaU54TtQtAIg/ZBAfm0aje/mo3MRDo3P0hZSgr4U7O3xfX+fQmR5AP04JS/TGcZLcFA==", "license": "MIT", "dependencies": { - "type-fest": "^3.8.0" + "@oxc-project/types": "^0.127.0" }, "engines": { - "node": ">=16" + "node": "^20.19.0 || >=22.12.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ow/node_modules/type-fest": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=14.16" + "url": "https://github.com/sponsors/Boshen" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", - "license": "MIT", - "engines": { - "node": ">=4" + "optionalDependencies": { + "@oxc-parser/binding-android-arm-eabi": "0.127.0", + "@oxc-parser/binding-android-arm64": "0.127.0", + "@oxc-parser/binding-darwin-arm64": "0.127.0", + "@oxc-parser/binding-darwin-x64": "0.127.0", + "@oxc-parser/binding-freebsd-x64": "0.127.0", + "@oxc-parser/binding-linux-arm-gnueabihf": "0.127.0", + "@oxc-parser/binding-linux-arm-musleabihf": "0.127.0", + "@oxc-parser/binding-linux-arm64-gnu": "0.127.0", + "@oxc-parser/binding-linux-arm64-musl": "0.127.0", + "@oxc-parser/binding-linux-ppc64-gnu": "0.127.0", + "@oxc-parser/binding-linux-riscv64-gnu": "0.127.0", + "@oxc-parser/binding-linux-riscv64-musl": "0.127.0", + "@oxc-parser/binding-linux-s390x-gnu": "0.127.0", + "@oxc-parser/binding-linux-x64-gnu": "0.127.0", + "@oxc-parser/binding-linux-x64-musl": "0.127.0", + "@oxc-parser/binding-openharmony-arm64": "0.127.0", + "@oxc-parser/binding-wasm32-wasi": "0.127.0", + "@oxc-parser/binding-win32-arm64-msvc": "0.127.0", + "@oxc-parser/binding-win32-ia32-msvc": "0.127.0", + "@oxc-parser/binding-win32-x64-msvc": "0.127.0" + } + }, + "node_modules/oxc-resolver": { + "version": "11.19.1", + "resolved": "https://registry.npmjs.org/oxc-resolver/-/oxc-resolver-11.19.1.tgz", + "integrity": "sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxc-resolver/binding-android-arm-eabi": "11.19.1", + "@oxc-resolver/binding-android-arm64": "11.19.1", + "@oxc-resolver/binding-darwin-arm64": "11.19.1", + "@oxc-resolver/binding-darwin-x64": "11.19.1", + "@oxc-resolver/binding-freebsd-x64": "11.19.1", + "@oxc-resolver/binding-linux-arm-gnueabihf": "11.19.1", + "@oxc-resolver/binding-linux-arm-musleabihf": "11.19.1", + "@oxc-resolver/binding-linux-arm64-gnu": "11.19.1", + "@oxc-resolver/binding-linux-arm64-musl": "11.19.1", + "@oxc-resolver/binding-linux-ppc64-gnu": "11.19.1", + "@oxc-resolver/binding-linux-riscv64-gnu": "11.19.1", + "@oxc-resolver/binding-linux-riscv64-musl": "11.19.1", + "@oxc-resolver/binding-linux-s390x-gnu": "11.19.1", + "@oxc-resolver/binding-linux-x64-gnu": "11.19.1", + "@oxc-resolver/binding-linux-x64-musl": "11.19.1", + "@oxc-resolver/binding-openharmony-arm64": "11.19.1", + "@oxc-resolver/binding-wasm32-wasi": "11.19.1", + "@oxc-resolver/binding-win32-arm64-msvc": "11.19.1", + "@oxc-resolver/binding-win32-ia32-msvc": "11.19.1", + "@oxc-resolver/binding-win32-x64-msvc": "11.19.1" } }, "node_modules/p-each-series": { @@ -18999,15 +16554,19 @@ } }, "node_modules/p-event": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-1.3.0.tgz", - "integrity": "sha512-hV1zbA7gwqPVFcapfeATaNjQ3J0NuzorHPyG8GPL9g/Y/TplWVBVoCKCXL6Ej2zscrCEv195QNWJXuBH6XZuzA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-6.0.1.tgz", + "integrity": "sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==", + "dev": true, "license": "MIT", "dependencies": { - "p-timeout": "^1.1.1" + "p-timeout": "^6.1.2" }, "engines": { - "node": ">=4" + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-filter": { @@ -19026,38 +16585,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-filter/node_modules/p-map": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", - "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/p-is-promise": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", - "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -19089,42 +16616,12 @@ } }, "node_modules/p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/p-map-series": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-1.0.0.tgz", - "integrity": "sha512-4k9LlvY6Bo/1FcIdV33wqZQES0Py+iKISU9Uc8p8AjWoZPnFKMpVIVD3s0EYn4jzLh1I+WeUZkJ0Yoa4Qfw3Kg==", - "license": "MIT", - "dependencies": { - "p-reduce": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-map-series/node_modules/p-reduce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", - "integrity": "sha512-3Tx1T3oM1xO/Y8Gj0sWyE78EIJZ+t+aEmXUdvQgvGmSMri7aPTHoovbXEreWKkL5j21Er60XAWLTzKbAKYOujQ==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/p-pipe": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-4.0.0.tgz", - "integrity": "sha512-HkPfFklpZQPUKBFXzKFB6ihLriIHxnmuQdK9WmLDwe4hf2PdhhfWT/FJa+pc3bA1ywvKXtedxIRmd4Y7BTXE4w==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", + "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", "license": "MIT", "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -19141,15 +16638,16 @@ } }, "node_modules/p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha512-gb0ryzr+K2qFqFv6qi3khoeqMZF/+ajxQipEF6NteZVnvz9tzdsfAVj3lYtn1gAXvH5lfLwfxEII799gt/mRIA==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", + "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", + "dev": true, "license": "MIT", - "dependencies": { - "p-finally": "^1.0.0" - }, "engines": { - "node": ">=4" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-try": { @@ -19225,56 +16723,52 @@ "node": ">= 14" } }, - "node_modules/pac-resolver": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", - "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "node_modules/pac-proxy-agent/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==", "license": "MIT", - "dependencies": { - "degenerator": "^5.0.0", - "netmask": "^2.0.2" - }, "engines": { "node": ">= 14" } }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "license": "MIT", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/param-case/node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "node_modules/pac-proxy-agent/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==", "license": "MIT", "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" } }, - "node_modules/param-case/node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "node_modules/pac-proxy-agent/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==", "license": "MIT", "dependencies": { - "tslib": "^2.0.3" + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" } }, - "node_modules/param-case/node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", "license": "MIT", "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" } }, "node_modules/parent-module": { @@ -19311,6 +16805,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -19319,15 +16814,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", - "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", @@ -19354,56 +16840,8 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true, - "license": "MIT" - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/pascal-case/node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/pascal-case/node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "license": "MIT", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/path": { - "version": "0.12.7", - "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", - "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", - "license": "MIT", - "dependencies": { - "process": "^0.11.1", - "util": "^0.10.3" - } - }, - "node_modules/path-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/path-case/-/path-case-2.1.1.tgz", - "integrity": "sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==", - "license": "MIT", - "dependencies": { - "no-case": "^2.2.0" - } + "dev": true, + "license": "MIT" }, "node_modules/path-exists": { "version": "4.0.0", @@ -19414,12 +16852,6 @@ "node": ">=8" } }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "license": "(WTFPL OR MIT)" - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -19452,9 +16884,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.3.tgz", - "integrity": "sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ==", + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.0.tgz", + "integrity": "sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==", "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" @@ -19464,32 +16896,12 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/path-unified": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/path-unified/-/path-unified-0.2.0.tgz", - "integrity": "sha512-MNKqvrKbbbb5p7XHXV6ZAsf/1f/yJQa13S/fcX0uua8ew58Tgc6jXV+16JyAbnR/clgCH+euKDxrF2STxMHdrg==", - "license": "MIT" - }, - "node_modules/path/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "license": "ISC" - }, - "node_modules/path/node_modules/util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "license": "MIT", - "dependencies": { - "inherits": "2.0.3" - } - }, "node_modules/pathval": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", @@ -19499,32 +16911,6 @@ "node": ">= 14.16" } }, - "node_modules/peek-readable": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.4.2.tgz", - "integrity": "sha512-peBp3qZyuS6cNIJ2akRNG1uo1WJ1d0wTxg/fxMdZ0BqCVhx242bSFHM9eNqflfJVS9SsgkzgT/1UgnsurBOTMg==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/pegjs": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz", - "integrity": "sha512-qI5+oFNEGi3L5HAxDwN2LA4Gg7irF70Zs25edhjld9QemOgp0CbvMtbFcMvFtEo1OityPrcCzkQFB8JP/hxgow==", - "dev": true, - "license": "MIT", - "bin": { - "pegjs": "bin/pegjs" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -19549,40 +16935,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", - "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "license": "MIT", - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pirates": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", @@ -19753,9 +17105,9 @@ } }, "node_modules/postcss": { - "version": "8.5.9", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.9.tgz", - "integrity": "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==", + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", "funding": [ { "type": "opencollective", @@ -19772,7 +17124,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.11", + "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -19780,47 +17132,17 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/postcss-loader": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.2.1.tgz", - "integrity": "sha512-k98jtRzthjj3f76MYTs9JTpRqV1RaaMhEU0Lpw9OTmQZQdppg4B30VZ74BojuBHt3F4KyubHJoXCMUeM8Bqeow==", + "node_modules/postcss-bem-linter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-bem-linter/-/postcss-bem-linter-4.0.1.tgz", + "integrity": "sha512-jTG3uMo6n2YyxLBPLsRN+5R9djNJZ3mirAugvnYbZaZOwPmLb/MaQ2uql0fSdVYegjZBmX8tW5B0mfZigiXZ9Q==", "license": "MIT", "dependencies": { - "cosmiconfig": "^9.0.0", - "jiti": "^2.5.1", - "semver": "^7.6.2" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "minimatch": "^3.1.2", + "postcss-resolve-nested-selector": "^0.1.1" }, "peerDependencies": { - "@rspack/core": "0.x || ^1.0.0 || ^2.0.0-0", - "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/postcss-loader/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "postcss": "^8.4.21" } }, "node_modules/postcss-media-query-parser": { @@ -19829,65 +17151,6 @@ "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", "license": "MIT" }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", - "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", - "license": "ISC", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", - "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", - "license": "MIT", - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^7.0.0", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", - "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", - "license": "ISC", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "license": "ISC", - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, "node_modules/postcss-resolve-nested-selector": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", @@ -19986,20 +17249,12 @@ "node": ">= 0.8.0" } }, - "node_modules/prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/prettier": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.2.tgz", - "integrity": "sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", + "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -20022,25 +17277,16 @@ "node": ">=6.0.0" } }, - "node_modules/pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "license": "MIT", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, "node_modules/pretty-format": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", - "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", + "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", "license": "MIT", "dependencies": { - "@jest/schemas": "30.0.5", + "@jest/schemas": "30.4.1", "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" + "react-is-18": "npm:react-is@^18.3.1", + "react-is-19": "npm:react-is@^19.2.5" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -20062,6 +17308,7 @@ "version": "9.3.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz", "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==", + "dev": true, "license": "MIT", "dependencies": { "parse-ms": "^4.0.0" @@ -20073,19 +17320,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, "license": "MIT" }, "node_modules/progress": { @@ -20101,6 +17340,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true, "license": "ISC" }, "node_modules/proxy-agent": { @@ -20122,6 +17362,41 @@ "node": ">= 14" } }, + "node_modules/proxy-agent/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==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/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==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/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==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/proxy-agent/node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", @@ -20137,12 +17412,6 @@ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "license": "MIT" }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "license": "ISC" - }, "node_modules/pump": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", @@ -20154,24 +17423,27 @@ } }, "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "license": "MIT" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } }, "node_modules/puppeteer": { - "version": "24.40.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.40.0.tgz", - "integrity": "sha512-IxQbDq93XHVVLWHrAkFP7F7iHvb9o0mgfsSIMlhHb+JM+JjM1V4v4MNSQfcRWJopx9dsNOr9adYv0U5fm9BJBQ==", + "version": "24.43.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.43.1.tgz", + "integrity": "sha512-/FSOViCrqRdb1HDocpsM9Z1giA71gTQPUt3SpHGVRALKAy/rJr1fLFYZW9F23qPxqVxTHQnbh/5B5opJST3kAw==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.13.0", + "@puppeteer/browsers": "2.13.2", "chromium-bidi": "14.0.0", "cosmiconfig": "^9.0.0", - "devtools-protocol": "0.0.1581282", - "puppeteer-core": "24.40.0", - "typed-query-selector": "^2.12.1" + "devtools-protocol": "0.0.1608973", + "puppeteer-core": "24.43.1", + "typed-query-selector": "^2.12.2" }, "bin": { "puppeteer": "lib/cjs/puppeteer/node/cli.js" @@ -20181,18 +17453,18 @@ } }, "node_modules/puppeteer-core": { - "version": "24.40.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.40.0.tgz", - "integrity": "sha512-MWL3XbUCfVgGR0gRsidzT6oKJT2QydPLhMITU6HoVWiiv4gkb6gJi3pcdAa8q4HwjBTbqISOWVP4aJiiyUJvag==", + "version": "24.43.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.43.1.tgz", + "integrity": "sha512-T5ScUMAsmhdNbgDR41AGESYeS6V9MSgetkSnVhhW+gXvzC42VesKCn5ld87gAZDJ6vLHL9GkRvY9WtQWSnwFbw==", "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.13.0", + "@puppeteer/browsers": "2.13.2", "chromium-bidi": "14.0.0", "debug": "^4.4.3", - "devtools-protocol": "0.0.1581282", - "typed-query-selector": "^2.12.1", + "devtools-protocol": "0.0.1608973", + "typed-query-selector": "^2.12.2", "webdriver-bidi-protocol": "0.4.1", - "ws": "^8.19.0" + "ws": "^8.20.0" }, "engines": { "node": ">=18" @@ -20215,9 +17487,9 @@ "license": "MIT" }, "node_modules/qified": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/qified/-/qified-0.9.1.tgz", - "integrity": "sha512-n7mar4T0xQ+39dE2vGTAlbxUEpndwPANH0kDef1/MYsB8Bba9wshkybIRx74qgcvKQPEWErf9AqAdYjhzY2Ilg==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/qified/-/qified-0.10.1.tgz", + "integrity": "sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==", "license": "MIT", "dependencies": { "hookified": "^2.1.1" @@ -20227,40 +17499,11 @@ } }, "node_modules/qified/node_modules/hookified": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/hookified/-/hookified-2.1.1.tgz", - "integrity": "sha512-AHb76R16GB5EsPBE2J7Ko5kiEyXwviB9P5SMrAKcuAu4vJPZttViAbj9+tZeaQE5zjDme+1vcHP78Yj/WoAveA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-2.2.0.tgz", + "integrity": "sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==", "license": "MIT" }, - "node_modules/qs": { - "version": "6.15.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", - "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "license": "MIT", - "dependencies": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -20291,15 +17534,6 @@ "url": "https://opencollective.com/ramda" } }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -20316,29 +17550,107 @@ "rc": "cli.js" } }, - "node_modules/rc/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "license": "ISC" - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", + "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-docgen": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-8.0.3.tgz", + "integrity": "sha512-aEZ9qP+/M+58x2qgfSFEWH1BxLyHe5+qkLNJOZQb5iGS017jpbRnoKhNRrXPeA6RfBrZO5wZrT9DMC1UqE1f1w==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/traverse": "^7.28.0", + "@babel/types": "^7.28.2", + "@types/babel__core": "^7.20.5", + "@types/babel__traverse": "^7.20.7", + "@types/doctrine": "^0.0.9", + "@types/resolve": "^1.20.2", + "doctrine": "^3.0.0", + "resolve": "^1.22.1", + "strip-indent": "^4.0.0" + }, + "engines": { + "node": "^20.9.0 || >=22" + } + }, + "node_modules/react-docgen-typescript": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-2.4.0.tgz", + "integrity": "sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==", + "license": "MIT", + "peerDependencies": { + "typescript": ">= 4.3.x" + } + }, + "node_modules/react-docgen/node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.6.tgz", + "integrity": "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==", "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.6" } }, "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==", + "license": "MIT", + "peer": true + }, + "node_modules/react-is-18": { + "name": "react-is", "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "license": "MIT" }, + "node_modules/react-is-19": { + "name": "react-is", + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.6.tgz", + "integrity": "sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw==", + "license": "MIT" + }, "node_modules/read-package-up": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz", @@ -20425,6 +17737,7 @@ "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", @@ -20436,22 +17749,24 @@ "util-deprecate": "~1.0.1" } }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "node_modules/readable-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, "license": "MIT" }, "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, "engines": { - "node": ">=8.10.0" + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, "node_modules/recast": { @@ -20482,31 +17797,53 @@ "node": ">=4" } }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "license": "MIT", "dependencies": { - "resolve": "^1.20.0" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">=8" } }, - "node_modules/redent": { + "node_modules/redent/node_modules/strip-indent": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "license": "MIT", "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" + "min-indent": "^1.0.0" }, "engines": { "node": ">=8" } }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -20540,6 +17877,26 @@ "regexp-tree": "bin/regexp-tree" } }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regexpu-core": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", @@ -20588,28 +17945,6 @@ "regjsparser": "bin/parser" } }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "license": "MIT", - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -20628,31 +17963,13 @@ "node": ">=0.10.0" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true, - "license": "ISC" - }, - "node_modules/reserved-identifiers": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/reserved-identifiers/-/reserved-identifiers-1.2.0.tgz", - "integrity": "sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/resolve": { - "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", "license": "MIT", "dependencies": { + "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" @@ -20679,19 +17996,6 @@ "node": ">=8" } }, - "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==", - "license": "MIT", - "dependencies": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -20701,29 +18005,6 @@ "node": ">=8" } }, - "node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", - "license": "MIT", - "dependencies": { - "lowercase-keys": "^1.0.0" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -20741,24 +18022,56 @@ "dev": true, "license": "MIT" }, - "node_modules/rimraf": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", - "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", - "license": "ISC", + "node_modules/rollup": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.4.tgz", + "integrity": "sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==", + "license": "MIT", "dependencies": { - "glob": "^9.2.0" + "@types/estree": "1.0.8" }, "bin": { - "rimraf": "dist/cjs/src/bin.js" + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14" + "node": ">=18.0.0", + "npm": ">=8.0.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.60.4", + "@rollup/rollup-android-arm64": "4.60.4", + "@rollup/rollup-darwin-arm64": "4.60.4", + "@rollup/rollup-darwin-x64": "4.60.4", + "@rollup/rollup-freebsd-arm64": "4.60.4", + "@rollup/rollup-freebsd-x64": "4.60.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.4", + "@rollup/rollup-linux-arm-musleabihf": "4.60.4", + "@rollup/rollup-linux-arm64-gnu": "4.60.4", + "@rollup/rollup-linux-arm64-musl": "4.60.4", + "@rollup/rollup-linux-loong64-gnu": "4.60.4", + "@rollup/rollup-linux-loong64-musl": "4.60.4", + "@rollup/rollup-linux-ppc64-gnu": "4.60.4", + "@rollup/rollup-linux-ppc64-musl": "4.60.4", + "@rollup/rollup-linux-riscv64-gnu": "4.60.4", + "@rollup/rollup-linux-riscv64-musl": "4.60.4", + "@rollup/rollup-linux-s390x-gnu": "4.60.4", + "@rollup/rollup-linux-x64-gnu": "4.60.4", + "@rollup/rollup-linux-x64-musl": "4.60.4", + "@rollup/rollup-openbsd-x64": "4.60.4", + "@rollup/rollup-openharmony-arm64": "4.60.4", + "@rollup/rollup-win32-arm64-msvc": "4.60.4", + "@rollup/rollup-win32-ia32-msvc": "4.60.4", + "@rollup/rollup-win32-x64-gnu": "4.60.4", + "@rollup/rollup-win32-x64-msvc": "4.60.4", + "fsevents": "~2.3.2" } }, + "node_modules/rollup/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==", + "license": "MIT" + }, "node_modules/rrweb-cssom": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", @@ -20777,16 +18090,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -20819,150 +18122,98 @@ "tslib": "^2.1.0" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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/safe-identifier": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/safe-identifier/-/safe-identifier-0.4.2.tgz", - "integrity": "sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==", - "license": "ISC" - }, - "node_modules/safe-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", - "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", - "license": "MIT", - "dependencies": { - "regexp-tree": "~0.1.1" - } - }, - "node_modules/safe-regex-test": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", - "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "node_modules/safe-array-concat": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", + "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-regex": "^1.2.1" + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" }, "engines": { - "node": ">= 0.4" + "node": ">=0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, "license": "MIT" }, - "node_modules/sass": { - "version": "1.99.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.99.0.tgz", - "integrity": "sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q==", + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", "license": "MIT", "dependencies": { - "chokidar": "^4.0.0", - "immutable": "^5.1.5", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "bin": { - "sass": "sass.js" + "es-errors": "^1.3.0", + "isarray": "^2.0.5" }, "engines": { - "node": ">=14.0.0" + "node": ">= 0.4" }, - "optionalDependencies": { - "@parcel/watcher": "^2.4.1" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/sass-loader": { - "version": "16.0.7", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.7.tgz", - "integrity": "sha512-w6q+fRHourZ+e+xA1kcsF27iGM6jdB8teexYCfdUw0sYgcDNeZESnDNT9sUmmPm3ooziwUJXGwZJSTF3kOdBfA==", + "node_modules/safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", "license": "MIT", "dependencies": { - "neo-async": "^2.6.2" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || ^1.0.0 || ^2.0.0-0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", - "sass": "^1.3.0", - "sass-embedded": "*", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "node-sass": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "webpack": { - "optional": true - } + "regexp-tree": "~0.1.1" } }, - "node_modules/sass/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "license": "MIT", "dependencies": { - "readdirp": "^4.0.1" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" }, "engines": { - "node": ">= 14.16.0" + "node": ">= 0.4" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/sass/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.100.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.100.0.tgz", + "integrity": "sha512-B5j0rYMlinhhOo9tjQebMVVn0TfyXAF+wB3b2ggZUuJ/is/Y+7+JGjirAMxHZ9Z3hIP98NPfamlAkBHa1lAaXQ==", "license": "MIT", + "dependencies": { + "chokidar": "^5.0.0", + "immutable": "^5.1.5", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, "engines": { - "node": ">= 14.18.0" + "node": ">=20.19.0" }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" } }, "node_modules/sax": { @@ -20970,7 +18221,6 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", "license": "BlueOak-1.0.0", - "peer": true, "engines": { "node": ">=11.0.0" } @@ -20987,42 +18237,10 @@ "node": ">=v12.22.7" } }, - "node_modules/schema-utils": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", - "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/seek-bzip": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", - "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", - "license": "MIT", - "dependencies": { - "commander": "^2.8.1" - }, - "bin": { - "seek-bunzip": "bin/seek-bunzip", - "seek-table": "bin/seek-bzip-table" - } - }, - "node_modules/seek-bzip/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, "node_modules/semantic-release": { @@ -21111,28 +18329,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semantic-release/node_modules/cliui": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", - "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^7.2.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/semantic-release/node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "dev": true, - "license": "MIT" - }, "node_modules/semantic-release/node_modules/escape-string-regexp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", @@ -21206,40 +18402,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semantic-release/node_modules/find-versions": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-6.0.0.tgz", - "integrity": "sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver-regex": "^4.0.5", - "super-regex": "^1.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/semantic-release/node_modules/hosted-git-info": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", - "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.3.tgz", + "integrity": "sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==", "dev": true, "license": "ISC", "dependencies": { @@ -21286,9 +18452,9 @@ } }, "node_modules/semantic-release/node_modules/lru-cache": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.3.tgz", - "integrity": "sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ==", + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.0.tgz", + "integrity": "sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -21436,9 +18602,9 @@ } }, "node_modules/semantic-release/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", "dev": true, "license": "ISC", "bin": { @@ -21448,19 +18614,6 @@ "node": ">=10" } }, - "node_modules/semantic-release/node_modules/semver-regex": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", - "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/semantic-release/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -21474,40 +18627,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/semantic-release/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/semantic-release/node_modules/strip-final-newline": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", @@ -21522,9 +18641,9 @@ } }, "node_modules/semantic-release/node_modules/type-fest": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.5.0.tgz", - "integrity": "sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.6.0.tgz", + "integrity": "sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==", "dev": true, "license": "(MIT OR CC0-1.0)", "dependencies": { @@ -21550,34 +18669,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semantic-release/node_modules/yargs": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", - "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^9.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "string-width": "^7.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^22.0.0" - }, - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=23" - } - }, - "node_modules/semantic-release/node_modules/yargs-parser": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", - "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=23" - } - }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -21588,61 +18679,18 @@ } }, "node_modules/semver-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", - "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", + "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==", + "dev": true, "license": "MIT", "engines": { - "node": ">=6" - } - }, - "node_modules/semver-truncate": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz", - "integrity": "sha512-V1fGg9i4CL3qesB6U0L6XAm4xOJiHmt4QAacazumuasc03BvtFGIMCduv01JWQ69Nv+JST9TqhSCiJoxoY031w==", - "license": "MIT", - "dependencies": { - "semver": "^5.3.0" + "node": ">=12" }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/semver-truncate/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/sentence-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-2.1.1.tgz", - "integrity": "sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==", - "license": "MIT", - "dependencies": { - "no-case": "^2.2.0", - "upper-case-first": "^1.1.2" - } - }, - "node_modules/serialize-javascript": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", - "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=20.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true, - "license": "ISC" - }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -21660,16 +18708,33 @@ "node": ">= 0.4" } }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", "license": "MIT", "dependencies": { - "kind-of": "^6.0.2" + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, "node_modules/shebang-command": { @@ -21890,15 +18955,15 @@ } }, "node_modules/simple-git": { - "version": "3.35.2", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.35.2.tgz", - "integrity": "sha512-ZMjl06lzTm1EScxEGuM6+mEX+NQd14h/B3x0vWU+YOXAMF8sicyi1K4cjTfj5is+35ChJEHDl1EjypzYFWH2FA==", + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.36.0.tgz", + "integrity": "sha512-cGQjLjK8bxJw4QuYT7gxHw3/IouVESbhahSsHrX97MzCL1gu2u7oy38W6L2ZIGECEfIBG4BabsWDPjBxJENv9Q==", "license": "MIT", "dependencies": { "@kwsites/file-exists": "^1.1.1", "@kwsites/promise-deferred": "^1.1.1", - "@simple-git/args-pathspec": "^1.0.2", - "@simple-git/argv-parser": "^1.0.3", + "@simple-git/args-pathspec": "^1.0.3", + "@simple-git/argv-parser": "^1.1.0", "debug": "^4.4.0" }, "funding": { @@ -21920,15 +18985,12 @@ } }, "node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "license": "MIT", "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/slice-ansi": { @@ -21971,22 +19033,13 @@ "npm": ">= 3.0.0" } }, - "node_modules/snake-case": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz", - "integrity": "sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==", - "license": "MIT", - "dependencies": { - "no-case": "^2.2.0" - } - }, "node_modules/socks": { - "version": "2.8.7", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", - "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.9.tgz", + "integrity": "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==", "license": "MIT", "dependencies": { - "ip-address": "^10.0.1", + "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" }, "engines": { @@ -22001,44 +19054,20 @@ "license": "MIT", "dependencies": { "agent-base": "^7.1.2", - "debug": "^4.3.4", - "socks": "^2.8.3" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", - "license": "MIT", - "dependencies": { - "is-plain-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sort-keys-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", - "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", - "license": "MIT", - "dependencies": { - "sort-keys": "^1.0.0" + "debug": "^4.3.4", + "socks": "^2.8.3" }, "engines": { - "node": ">=0.10.0" + "node": ">= 14" } }, - "node_modules/sort-keys/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "node_modules/socks-proxy-agent/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==", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 14" } }, "node_modules/source-map": { @@ -22149,45 +19178,87 @@ "node": ">=8" } }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/storybook": { - "version": "9.1.20", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-9.1.20.tgz", - "integrity": "sha512-6rME2tww6PFhm96iG2Xx44yzwLDWBiDWy+kJ2ub6x90werSTOiuo+tZJ94BgCfFutR0tEfLRIq59s+Zg6YyChA==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.4.1.tgz", + "integrity": "sha512-V1Zd2e+gBFufqAQVZ1JR8KLqALsEZ3JYSBnWwQbKa6zCfWWanR6AFMyuOkLt2gZOgGp3h2Riuz88pGNVTQSG0A==", "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", - "@testing-library/jest-dom": "^6.6.3", + "@storybook/icons": "^2.0.2", + "@testing-library/jest-dom": "^6.9.1", "@testing-library/user-event": "^14.6.1", "@vitest/expect": "3.2.4", - "@vitest/mocker": "3.2.4", "@vitest/spy": "3.2.4", - "better-opn": "^3.0.2", - "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", - "esbuild-register": "^3.5.0", + "@webcontainer/env": "^1.1.1", + "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0", + "open": "^10.2.0", + "oxc-parser": "^0.127.0", + "oxc-resolver": "^11.19.1", "recast": "^0.23.5", - "semver": "^7.6.2", + "semver": "^7.7.3", + "use-sync-external-store": "^1.5.0", "ws": "^8.18.0" }, "bin": { - "storybook": "bin/index.cjs" + "storybook": "dist/bin/dispatcher.js" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "prettier": "^2 || ^3" + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "prettier": "^2 || ^3", + "vite-plus": "^0.1.15" }, "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, "prettier": { "optional": true + }, + "vite-plus": { + "optional": true } } }, + "node_modules/storybook/node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/storybook/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -22196,13 +19267,19 @@ "node": ">=10" } }, - "node_modules/stream": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.3.tgz", - "integrity": "sha512-aMsbn7VKrl4A2T7QAQQbzgN7NVc70vgF5INQrBXqn4dCXN1zy3L9HGgLO5s7PExmdrzTJ8uR/27aviW8or8/+A==", + "node_modules/storybook/node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", "license": "MIT", "dependencies": { - "component-emitter": "^2.0.0" + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/stream-combiner2": { @@ -22227,30 +19304,16 @@ "text-decoder": "^1.1.0" } }, - "node_modules/strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, "node_modules/string-argv": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", @@ -22297,6 +19360,62 @@ "node": ">=8" } }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -22327,24 +19446,6 @@ "node": ">=8" } }, - "node_modules/strip-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", - "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", - "license": "MIT", - "dependencies": { - "is-natural-number": "^4.0.1" - } - }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -22355,15 +19456,15 @@ } }, "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.1.1.tgz", + "integrity": "sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==", "license": "MIT", - "dependencies": { - "min-indent": "^1.0.0" - }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/strip-json-comments": { @@ -22378,109 +19479,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-outer/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/strtok3": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-9.1.1.tgz", - "integrity": "sha512-FhwotcEqjr241ZbjFzjlIYg6c5/L/s4yBGWSMvJ9UoExiSqL+FnFA/CaeZx17WGaZMS/4SOZp8wH18jSS4R4lw==", + "version": "10.3.5", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.5.tgz", + "integrity": "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==", "license": "MIT", "dependencies": { - "@tokenizer/token": "^0.3.0", - "peek-readable": "^5.3.1" + "@tokenizer/token": "^0.3.0" }, "engines": { - "node": ">=16" + "node": ">=18" }, "funding": { "type": "github", "url": "https://github.com/sponsors/Borewit" } }, - "node_modules/style-dictionary": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/style-dictionary/-/style-dictionary-5.4.0.tgz", - "integrity": "sha512-6BzO0DV19t6KUEXYfvHJ73d3y8bBDcd0wNLfoZRX817obJ8YX5Vev8Xh3+k9601tHE8qRJ/586iLt0byuY2THw==", - "license": "Apache-2.0", - "dependencies": { - "@bundled-es-modules/deepmerge": "^4.3.1", - "@bundled-es-modules/glob": "^13.0.6", - "@bundled-es-modules/memfs": "^4.17.0", - "@zip.js/zip.js": "^2.7.44", - "chalk": "^5.3.0", - "change-case": "^5.3.0", - "colorjs.io": "^0.5.2", - "commander": "^12.1.0", - "is-plain-obj": "^4.1.0", - "json5": "^2.2.2", - "path-unified": "^0.2.0", - "prettier": "^3.3.3", - "tinycolor2": "^1.6.0" - }, - "bin": { - "style-dictionary": "bin/style-dictionary.js" - }, - "engines": { - "node": ">=22.0.0" - } - }, - "node_modules/style-dictionary/node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/style-dictionary/node_modules/change-case": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", - "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", - "license": "MIT" - }, - "node_modules/style-loader": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", - "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", - "license": "MIT", - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, "node_modules/stylelint": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-17.7.0.tgz", - "integrity": "sha512-n/+4RheCRl+cecGnF+S/Adz59iCRaK9BVznJYB+a7GOksfwNzjiOPnYv17pTO0HgRse9IiqbMtekGNhOb2tVYQ==", + "version": "17.12.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-17.12.0.tgz", + "integrity": "sha512-KIlzWXMHUvgfPUR0R7TK3H80yCIi0uoivUwf+6Az4yrHJD1Q3c1qIkh/H5Z0i/K3QXgtq/UMEkWyBUSUwnpnOg==", "funding": [ { "type": "opencollective", @@ -22493,9 +19511,9 @@ ], "license": "MIT", "dependencies": { - "@csstools/css-calc": "^3.1.1", + "@csstools/css-calc": "^3.2.0", "@csstools/css-parser-algorithms": "^4.0.0", - "@csstools/css-syntax-patches-for-csstree": "^1.1.2", + "@csstools/css-syntax-patches-for-csstree": "^1.1.3", "@csstools/css-tokenizer": "^4.0.0", "@csstools/media-query-list-parser": "^5.0.0", "@csstools/selector-resolve-nested": "^4.0.0", @@ -22507,24 +19525,23 @@ "debug": "^4.4.3", "fast-glob": "^3.3.3", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^11.1.2", + "file-entry-cache": "^11.1.3", "global-modules": "^2.0.0", "globby": "^16.2.0", "globjoin": "^0.1.4", "html-tags": "^5.1.0", "ignore": "^7.0.5", "import-meta-resolve": "^4.2.0", - "is-plain-object": "^5.0.0", "mathml-tag-names": "^4.0.0", "meow": "^14.1.0", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "picocolors": "^1.1.1", - "postcss": "^8.5.8", + "postcss": "^8.5.14", "postcss-safe-parser": "^7.0.1", "postcss-selector-parser": "^7.1.1", "postcss-value-parser": "^4.2.0", - "string-width": "^8.2.0", + "string-width": "^8.2.1", "supports-hyperlinks": "^4.4.0", "svg-tags": "^1.0.0", "table": "^6.9.0", @@ -22646,15 +19663,18 @@ } }, "node_modules/stylelint-scss": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-7.0.0.tgz", - "integrity": "sha512-H88kCC+6Vtzj76NsC8rv6x/LW8slBzIbyeSjsKVlS+4qaEJoDrcJR4L+8JdrR2ORdTscrBzYWiiT2jq6leYR1Q==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-7.1.1.tgz", + "integrity": "sha512-pLPXJZ7RtAFNLXe8gqarf3B56ScVTd1vPiL9IFgcJkIZsYPzAgLJPh2h9NHrp3BFeKrtAkIgwQ08QSmhvlv1gA==", "license": "MIT", "dependencies": { - "css-tree": "^3.0.1", + "@csstools/css-calc": "^3.2.0", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-syntax-patches-for-csstree": "^1.1.3", + "@csstools/css-tokenizer": "^4.0.0", + "css-tree": "^3.2.1", "is-plain-object": "^5.0.0", "known-css-properties": "^0.37.0", - "mdn-data": "^2.25.0", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.6", "postcss-selector-parser": "^7.1.1", @@ -22667,169 +19687,90 @@ "stylelint": "^16.8.2 || ^17.0.0" } }, - "node_modules/stylelint-webpack-plugin": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/stylelint-webpack-plugin/-/stylelint-webpack-plugin-5.1.0.tgz", - "integrity": "sha512-A7HR+g2W9lpc72QaF6LM1E+e9E3B7pl2hIV8rK8OiF3plbs0nf7ipixYf7MGvPgmQF+us63xmo7PV0W/RH3UDQ==", - "license": "MIT", - "dependencies": { - "globby": "^11.1.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "schema-utils": "^4.2.0" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "stylelint": "^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0", - "webpack": "^5.0.0" - } - }, - "node_modules/stylelint-webpack-plugin/node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/stylelint-webpack-plugin/node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/stylelint-webpack-plugin/node_modules/@sinclair/typebox": { - "version": "0.27.10", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", - "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==", - "license": "MIT" - }, - "node_modules/stylelint-webpack-plugin/node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/stylelint-webpack-plugin/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "node_modules/stylelint-scss/node_modules/@csstools/css-calc": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.1.tgz", + "integrity": "sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==", "funding": [ { "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" } ], "license": "MIT", "engines": { - "node": ">=8" - } - }, - "node_modules/stylelint-webpack-plugin/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" + "node": ">=20.19.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" } }, - "node_modules/stylelint-webpack-plugin/node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "node_modules/stylelint-scss/node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/stylelint-webpack-plugin/node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "node": ">=20.19.0" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" } }, - "node_modules/stylelint-webpack-plugin/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/stylelint-scss/node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "license": "MIT", "engines": { - "node": ">=8" + "node": ">=20.19.0" } }, - "node_modules/stylelint-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/stylelint-selector-bem-pattern": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/stylelint-selector-bem-pattern/-/stylelint-selector-bem-pattern-5.0.0.tgz", + "integrity": "sha512-nXcfLw2mZkNCyTLYPESavGLfWhY1RrjzsjVufbpKsMTH65WeOYGwouB3yqyV8l4WtKMVniz29LlELJcJ0d660A==", "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "postcss": "^8.5.6", + "postcss-bem-linter": "^4.0.1" }, "engines": { - "node": ">=10" + "node": ">=24.13.0" }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "peerDependencies": { + "stylelint": "^17.0.0" } }, "node_modules/stylelint/node_modules/@csstools/css-calc": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz", - "integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.1.tgz", + "integrity": "sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==", "funding": [ { "type": "github", @@ -22914,12 +19855,12 @@ } }, "node_modules/stylelint/node_modules/file-entry-cache": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.2.tgz", - "integrity": "sha512-N2WFfK12gmrK1c1GXOqiAJ1tc5YE+R53zvQ+t5P8S5XhnmKYVB5eZEiLNZKDSmoG8wqqbF9EXYBBW/nef19log==", + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.3.tgz", + "integrity": "sha512-oMbq0PD6VIiIwMF6LIa7MEwd/l9huKwmqRKXqmrkqIZv8CvRbfowL+L0ryAl8h//HfAS0zS+4SbYoRyAoA6BJA==", "license": "MIT", "dependencies": { - "flat-cache": "^6.1.20" + "flat-cache": "^6.1.22" } }, "node_modules/stylelint/node_modules/flat-cache": { @@ -22933,52 +19874,6 @@ "hookified": "^1.15.0" } }, - "node_modules/stylelint/node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "license": "MIT", - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/stylelint/node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "license": "MIT", - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/stylelint/node_modules/globby": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-16.2.0.tgz", - "integrity": "sha512-QrJia2qDf5BB/V6HYlDTs0I0lBahyjLzpGQg3KT7FnCdTonAyPy2RtY802m2k4ALx6Dp752f82WsOczEVr3l6Q==", - "license": "MIT", - "dependencies": { - "@sindresorhus/merge-streams": "^4.0.0", - "fast-glob": "^3.3.3", - "ignore": "^7.0.5", - "is-path-inside": "^4.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.4.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/stylelint/node_modules/has-flag": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz", @@ -23000,24 +19895,6 @@ "node": ">= 4" } }, - "node_modules/stylelint/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "license": "ISC" - }, - "node_modules/stylelint/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==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/stylelint/node_modules/meow": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/meow/-/meow-14.1.0.tgz", @@ -23043,9 +19920,9 @@ } }, "node_modules/stylelint/node_modules/string-width": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.0.tgz", - "integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", + "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", "license": "MIT", "dependencies": { "get-east-asian-width": "^1.5.0", @@ -23101,30 +19978,6 @@ "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" } }, - "node_modules/stylelint/node_modules/unicorn-magic": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", - "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", - "license": "MIT", - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/stylelint/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, "node_modules/stylelint/node_modules/write-file-atomic": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-7.0.1.tgz", @@ -23141,6 +19994,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-1.1.0.tgz", "integrity": "sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ==", + "dev": true, "license": "MIT", "dependencies": { "function-timeout": "^1.0.1", @@ -23195,101 +20049,30 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/svg-element-attributes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/svg-element-attributes/-/svg-element-attributes-2.1.0.tgz", - "integrity": "sha512-Tq0WY3uGw/rltlSlAsro/WWqbg5oNiaRwzq13I9H1m/dYjMjesuxKV76dGSlpacjslGyAis8VIwqPXaUUXw26w==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/svg-spritemap-webpack-plugin": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/svg-spritemap-webpack-plugin/-/svg-spritemap-webpack-plugin-5.1.0.tgz", - "integrity": "sha512-0xtzMZQifsFmFxSsFdIN2SLxnDSU7WvbDYruIOlHFoEJT98htL65yCkpPeOiG/IetJVW7qKtPWqMSfrssk23lw==", - "license": "MIT", - "dependencies": { - "@xmldom/xmldom": "^0.9.8", - "glob": "^13.0.0", - "loader-utils": "^3.3.1", - "lodash-es": "^4.17.21", - "mini-svg-data-uri": "^1.4.4", - "mkdirp": "^3.0.1", - "svg-element-attributes": "^2.1.0", - "webpack-merge": "^6.0.1", - "webpack-sources": "^3.3.3", - "zod": "^4.1.13" - }, - "engines": { - "node": "^20.11.0 || ^21.2.0 || >= 22.0.0" - }, - "peerDependencies": { - "svg4everybody": "^2.1.9", - "svgo": "^4.0.0", - "typescript": "^4.0.0 || ^5.0.0", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/svg-spritemap-webpack-plugin/node_modules/loader-utils": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", - "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", - "license": "MIT", - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/svg-spritemap-webpack-plugin/node_modules/zod": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", - "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/svg-tags": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==" }, - "node_modules/svg4everybody": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/svg4everybody/-/svg4everybody-2.1.9.tgz", - "integrity": "sha512-AS9WORVV/vk520ZHxGTlQzyDBizp/h6WyAYUbKhze/kwvQr43DwJpkIIPBomsUyKqN7N+h1deF92N9PmW+o+9A==", - "license": "CC0-1.0", - "peer": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/svgo": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz", - "integrity": "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.3.tgz", + "integrity": "sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng==", "license": "MIT", - "peer": true, "dependencies": { - "commander": "^11.1.0", + "commander": "^7.2.0", "css-select": "^5.1.0", - "css-tree": "^3.0.1", + "css-tree": "^2.3.1", "css-what": "^6.1.0", "csso": "^5.0.5", - "picocolors": "^1.1.1", + "picocolors": "^1.0.0", "sax": "^1.5.0" }, "bin": { - "svgo": "bin/svgo.js" + "svgo": "bin/svgo" }, "engines": { - "node": ">=16" + "node": ">=14.0.0" }, "funding": { "type": "opencollective", @@ -23297,101 +20080,33 @@ } }, "node_modules/svgo/node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "license": "MIT", - "peer": true, "engines": { - "node": ">=16" - } - }, - "node_modules/svgo/node_modules/css-select": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", - "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" + "node": ">= 10" } }, - "node_modules/svgo/node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "node_modules/svgo/node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", "license": "MIT", - "peer": true, - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/svgo/node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/svgo/node_modules/domutils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", - "license": "BSD-2-Clause", - "peer": true, "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/svgo/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "peer": true, - "engines": { - "node": ">=0.12" + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/swap-case": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", - "integrity": "sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==", - "license": "MIT", - "dependencies": { - "lower-case": "^1.1.1", - "upper-case": "^1.1.1" + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, + "node_modules/svgo/node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "license": "CC0-1.0" + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -23468,19 +20183,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tapable": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.2.tgz", - "integrity": "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==", - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/tar-fs": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.2.tgz", @@ -23495,10 +20197,10 @@ "bare-path": "^3.0.0" } }, - "node_modules/tar-fs/node_modules/tar-stream": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.8.tgz", - "integrity": "sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==", + "node_modules/tar-stream": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.0.tgz", + "integrity": "sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==", "license": "MIT", "dependencies": { "b4a": "^1.6.4", @@ -23507,24 +20209,6 @@ "streamx": "^2.15.0" } }, - "node_modules/tar-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", - "license": "MIT", - "dependencies": { - "bl": "^1.0.0", - "buffer-alloc": "^1.2.0", - "end-of-stream": "^1.0.0", - "fs-constants": "^1.0.0", - "readable-stream": "^2.3.0", - "to-buffer": "^1.1.1", - "xtend": "^4.0.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/teex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", @@ -23535,25 +20219,12 @@ } }, "node_modules/temp-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", - "integrity": "sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/tempfile": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-2.0.0.tgz", - "integrity": "sha512-ZOn6nJUgvgC09+doCEF3oB+r3ag7kUvlsXEGX069QRD60p+P3uP7XG9N2/at+EyIRGSN//ZY3LyEotA1YpmjuA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", + "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", "license": "MIT", - "dependencies": { - "temp-dir": "^1.0.0", - "uuid": "^3.0.1" - }, "engines": { - "node": ">=4" + "node": ">=14.16" } }, "node_modules/tempy": { @@ -23586,15 +20257,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tempy/node_modules/temp-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", - "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", - "license": "MIT", - "engines": { - "node": ">=14.16" - } - }, "node_modules/tempy/node_modules/type-fest": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", @@ -23607,1467 +20269,1767 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/terser": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.1.tgz", - "integrity": "sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==", - "license": "BSD-2-Clause", + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "license": "ISC", "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.15.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" }, - "bin": { - "terser": "bin/terser" + "engines": { + "node": ">=8" + } + }, + "node_modules/text-decoder": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", + "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==", + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" }, "engines": { - "node": ">=10" + "node": ">=0.8" } }, - "node_modules/terser-webpack-plugin": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.4.0.tgz", - "integrity": "sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==", + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "jest-worker": "^27.4.5", - "schema-utils": "^4.3.0", - "terser": "^5.31.1" + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/time-span": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/time-span/-/time-span-5.1.0.tgz", + "integrity": "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "convert-hrtime": "^5.0.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.2.tgz", + "integrity": "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" }, "peerDependencies": { - "webpack": "^5.1.0" + "picomatch": "^3 || ^4" }, "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { + "picomatch": { "optional": true } } }, - "node_modules/terser-webpack-plugin/node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "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==", + "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==", + "license": "MIT" + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "license": "BSD-3-Clause" + }, + "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==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/token-types": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz", + "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==", + "license": "MIT", + "dependencies": { + "@borewit/text-codec": "^0.2.1", + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "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==", + "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==", "license": "MIT", "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "punycode": "^2.3.1" }, "engines": { - "node": ">= 10.13.0" + "node": ">=18" } }, - "node_modules/terser-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/traverse": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.8.tgz", + "integrity": "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==", + "dev": true, "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT" - }, - "node_modules/terser/node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" + "bin": { + "tree-kill": "cli.js" } }, - "node_modules/test-exclude/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "node_modules/tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", "license": "MIT" }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" } }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "license": "MIT", "engines": { - "node": "*" + "node": ">=6.10" } }, - "node_modules/text-decoder": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", - "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==", - "license": "Apache-2.0", + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "license": "MIT", "dependencies": { - "b4a": "^1.6.4" + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0" + "engines": { + "node": ">=4" } }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", "dev": true, "license": "MIT", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, "engines": { - "node": ">=0.8" + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } }, - "node_modules/thingies": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.6.0.tgz", - "integrity": "sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==", - "license": "MIT", - "engines": { - "node": ">=10.18" + "node_modules/twig": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/twig/-/twig-3.0.0.tgz", + "integrity": "sha512-cMfYLWAgdW15B7L5wmanmga113e4phQmo3rk5EFuUrQd99g7I3ncxgynS38P01m4ZXBDSdMYUTV1g3A66/Y56Q==", + "license": "BSD-2-Clause", + "dependencies": { + "@babel/runtime": "^7.8.4", + "locutus": "^3.0.9", + "minimatch": "^10", + "walk": "2.3.x" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" + "bin": { + "twigjs": "bin/twigjs" }, - "peerDependencies": { - "tslib": "^2" + "engines": { + "node": ">=22" } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "license": "MIT" - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, + "node_modules/twig-drupal-filters": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/twig-drupal-filters/-/twig-drupal-filters-3.2.0.tgz", + "integrity": "sha512-BSRyHsAII8/k9e7rLDOs/NtirIKxgHH7jKlLzCdjKAlRsNrAZQyFI0a3+SCt4PiqaZ6Zo9W+4/ZFlBJ0z+0AuA==", "license": "MIT", "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "object-keys": "^1.1.1", + "twig": "^1.15.4" } }, - "node_modules/time-span": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/time-span/-/time-span-5.1.0.tgz", - "integrity": "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==", - "license": "MIT", + "node_modules/twig-drupal-filters/node_modules/twig": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/twig/-/twig-1.17.1.tgz", + "integrity": "sha512-atxccyr/BHtb1gPMA7Lvki0OuU17XBqHsNH9lzDHt9Rr1293EVZOosSZabEXz/DPVikIW8ZDqSkEddwyJnQN2w==", + "license": "BSD-2-Clause", "dependencies": { - "convert-hrtime": "^5.0.0" + "@babel/runtime": "^7.8.4", + "locutus": "^2.0.11", + "minimatch": "3.0.x", + "walk": "2.3.x" }, - "engines": { - "node": ">=12" + "bin": { + "twigjs": "bin/twigjs" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=10" } }, - "node_modules/timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", + "node_modules/twig/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": "18 || 20 || >=22" } }, - "node_modules/tiny-invariant": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", - "license": "MIT" - }, - "node_modules/tinycolor2": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", - "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", - "license": "MIT" - }, - "node_modules/tinyexec": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.1.tgz", - "integrity": "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==", - "dev": true, + "node_modules/twig/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, "engines": { - "node": ">=18" + "node": "18 || 20 || >=22" } }, - "node_modules/tinyglobby": { - "version": "0.2.16", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", - "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", - "license": "MIT", + "node_modules/twig/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.4" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=12.0.0" + "node": "18 || 20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "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==", "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" + "dependencies": { + "prelude-ls": "^1.2.1" }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "node": ">= 0.8.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==", + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "license": "MIT", "engines": { - "node": ">=14.0.0" + "node": ">=4" } }, - "node_modules/tinyspy": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", - "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", - "license": "MIT", + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=14.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/title-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz", - "integrity": "sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==", + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "license": "MIT", "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.0.3" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" } }, - "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==", + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "license": "MIT", "dependencies": { - "tldts-core": "^6.1.86" + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, - "bin": { - "tldts": "bin/cli.js" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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==", - "license": "MIT" - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "license": "MIT", "dependencies": { - "os-tmpdir": "~1.0.2" + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { - "node": ">=0.6.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "license": "BSD-3-Clause" - }, - "node_modules/to-buffer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", - "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "license": "MIT", "dependencies": { - "isarray": "^2.0.5", - "safe-buffer": "^5.2.1", - "typed-array-buffer": "^1.0.3" + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/to-buffer/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "node_modules/typed-query-selector": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.2.tgz", + "integrity": "sha512-EOPFbyIub4ngnEdqi2yOcNeDLaX/0jcE1JoAXQDDMIthap7FoN795lc/SHfIq2d416VufXpM8z/lD+WRm2gfOQ==", "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==", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, "engines": { - "node": ">=8.0" + "node": ">=14.17" } }, - "node_modules/token-transformer": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/token-transformer/-/token-transformer-0.0.33.tgz", - "integrity": "sha512-0h7Cvo8trUcv6sZPyA+iNHsFEwIhN4FhXtYqgndHQNYub+dTDW8ZCQURBNDNa0PvJ8Xg2wqG1V/5WSwV0l6yOw==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "license": "MIT", - "dependencies": { - "yargs": "^17.6.2" - }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, "bin": { - "token-transformer": "cli.js" + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" } }, - "node_modules/token-types": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz", - "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==", + "node_modules/uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", "license": "MIT", - "dependencies": { - "@borewit/text-codec": "^0.2.1", - "@tokenizer/token": "^0.3.0", - "ieee754": "^1.2.1" - }, "engines": { - "node": ">=14.16" + "node": ">=18" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", - "license": "BSD-3-Clause", + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "license": "MIT", "dependencies": { - "tldts": "^6.1.32" + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" }, "engines": { - "node": ">=16" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tr46": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", - "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "node_modules/undici": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", + "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", + "dev": true, "license": "MIT", - "dependencies": { - "punycode": "^2.3.1" - }, "engines": { - "node": ">=18" + "node": ">=20.18.1" } }, - "node_modules/tr46/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "node_modules/undici-types": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "license": "MIT", "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/traverse": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.8.tgz", - "integrity": "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==", + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=4" } }, - "node_modules/tree-dump": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", - "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==", - "license": "Apache-2.0", + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "license": "MIT", "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">=4" } }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", "license": "MIT", - "bin": { - "tree-kill": "cli.js" + "engines": { + "node": ">=4" } }, - "node_modules/trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/trim-repeated/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", "license": "MIT", + "dependencies": { + "crypto-random-string": "^4.0.0" + }, "engines": { - "node": ">=0.8.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tryer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", - "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", - "license": "MIT" + "node_modules/universal-user-agent": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", + "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==", + "dev": true, + "license": "ISC" }, - "node_modules/ts-api-utils": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", - "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "license": "MIT", "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" + "node": ">= 10.0.0" } }, - "node_modules/ts-dedent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", - "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "node_modules/unplugin": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.11.tgz", + "integrity": "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==", "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "acorn": "^8.15.0", + "picomatch": "^4.0.3", + "webpack-virtual-modules": "^0.6.2" + }, "engines": { - "node": ">=6.10" + "node": ">=18.12.0" } }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "dev": true, + "node_modules/unplugin/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", "engines": { - "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "license": "Apache-2.0", + "node_modules/unrs-resolver": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", + "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==", + "hasInstallScript": true, + "license": "MIT", "dependencies": { - "safe-buffer": "^5.0.1" + "napi-postinstall": "^0.3.4" }, - "engines": { - "node": "*" + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.12.2", + "@unrs/resolver-binding-android-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-x64": "1.12.2", + "@unrs/resolver-binding-freebsd-x64": "1.12.2", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", + "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", + "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-musl": "1.12.2", + "@unrs/resolver-binding-openharmony-arm64": "1.12.2", + "@unrs/resolver-binding-wasm32-wasi": "1.12.2", + "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", + "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", + "@unrs/resolver-binding-win32-x64-msvc": "1.12.2" } }, - "node_modules/twig": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/twig/-/twig-1.17.1.tgz", - "integrity": "sha512-atxccyr/BHtb1gPMA7Lvki0OuU17XBqHsNH9lzDHt9Rr1293EVZOosSZabEXz/DPVikIW8ZDqSkEddwyJnQN2w==", - "license": "BSD-2-Clause", + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "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": { - "@babel/runtime": "^7.8.4", - "locutus": "^2.0.11", - "minimatch": "3.0.x", - "walk": "2.3.x" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { - "twigjs": "bin/twigjs" + "update-browserslist-db": "cli.js" }, - "engines": { - "node": ">=10" + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "node_modules/twig-drupal-filters": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/twig-drupal-filters/-/twig-drupal-filters-3.2.0.tgz", - "integrity": "sha512-BSRyHsAII8/k9e7rLDOs/NtirIKxgHH7jKlLzCdjKAlRsNrAZQyFI0a3+SCt4PiqaZ6Zo9W+4/ZFlBJ0z+0AuA==", - "license": "MIT", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", "dependencies": { - "object-keys": "^1.1.1", - "twig": "^1.15.4" + "punycode": "^2.1.0" } }, - "node_modules/twig-testing-library": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/twig-testing-library/-/twig-testing-library-1.2.0.tgz", - "integrity": "sha512-8ybNtyE25BcqG5f2+vnrUydbOPJEOlXhKzWR/dDzyUpenCs4346UBWsTPhaOc4eRPiEofALfRR/BVOmU5lF+cQ==", + "node_modules/url-join": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", + "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", + "dev": true, "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@testing-library/dom": "^7.30.3", - "core-js": "^3.10.2", - "drupal-attribute": "^1.0.2", - "twig": "^1.15.4" + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/twig-testing-library/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.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==", + "license": "MIT" + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "license": "ISC", "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=10.12.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, - "node_modules/twig-testing-library/node_modules/@testing-library/dom": { - "version": "7.31.2", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-7.31.2.tgz", - "integrity": "sha512-3UqjCpey6HiTZT92vODYLPxTBWlM8ZOOjr3LX5F37/VRipW2M1kX6I/Cm4VXzteZqfGfagg8yXywpcOgQBlNsQ==", + "node_modules/vite": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.3.tgz", + "integrity": "sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^4.2.2", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.6", - "lz-string": "^1.4.4", - "pretty-format": "^26.6.2" + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" }, "engines": { - "node": ">=10" + "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/twig-testing-library/node_modules/@types/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", - "license": "MIT" - }, - "node_modules/twig-testing-library/node_modules/@types/yargs": { - "version": "15.0.20", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.20.tgz", - "integrity": "sha512-KIkX+/GgfFitlASYCGoSF+T4XRXhOubJLhkLVtSfsRTe9jWMmuM2g28zQ41BtPTG7TRBb2xHW+LCNVE9QR/vsg==", + "node_modules/vite-plugin-sass-glob-import": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vite-plugin-sass-glob-import/-/vite-plugin-sass-glob-import-6.0.3.tgz", + "integrity": "sha512-pVqBO5c6BDq5YZl2vORJLPUTDnER9ariMnPoY9HZd4qs/WU0bdWhyupKDGixodtk/BJJ78cEYrwZkEm0naMxkA==", "license": "MIT", "dependencies": { - "@types/yargs-parser": "*" + "ansi-colors": "4.1.3", + "glob": "13.0.6", + "minimatch": "10.2.4" + }, + "peerDependencies": { + "vite": "^6.0.0 || ^7.0.0" } }, - "node_modules/twig-testing-library/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==", + "node_modules/vite-plugin-sass-glob-import/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", "engines": { - "node": ">=8" + "node": "18 || 20 || >=22" } }, - "node_modules/twig-testing-library/node_modules/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", - "license": "Apache-2.0", + "node_modules/vite-plugin-sass-glob-import/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">=6.0" + "node": "18 || 20 || >=22" } }, - "node_modules/twig-testing-library/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "license": "MIT", + "node_modules/vite-plugin-sass-glob-import/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "license": "BlueOak-1.0.0", "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">= 10" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/twig-testing-library/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==", - "license": "MIT" - }, - "node_modules/twig/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==", - "license": "MIT" + "node_modules/vite-plugin-static-copy": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-4.1.0.tgz", + "integrity": "sha512-9XOarNV7LgP0KBB7AApxdgFikLXx3daZdqjC3AevYsL6MrUH62zphonLUs2a6LZc1HN1GY+vQdheZ8VVJb6dQQ==", + "license": "MIT", + "dependencies": { + "chokidar": "^3.6.0", + "p-map": "^7.0.4", + "picocolors": "^1.1.1", + "tinyglobby": "^0.2.15" + }, + "engines": { + "node": "^22.0.0 || >=24.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/sapphi-red" + }, + "peerDependencies": { + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + } }, - "node_modules/twig/node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "node_modules/vite-plugin-static-copy/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "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/twig/node_modules/minimatch": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", - "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "node_modules/vite-plugin-static-copy/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==", "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "is-glob": "^4.0.1" }, "engines": { - "node": "*" + "node": ">= 6" } }, - "node_modules/twigjs-loader": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/twigjs-loader/-/twigjs-loader-1.0.3.tgz", - "integrity": "sha512-a9UswA1d3Fdc7XlAoiqgqhjeoiv0U1oh7JbIudnatc+ATX7xXlrop9lz/d+s3gPg4hHVM+p6OmHzDjz+R56zhg==", + "node_modules/vite-plugin-static-copy/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "license": "MIT", - "engines": { - "node": ">=8.0" + "dependencies": { + "picomatch": "^2.2.1" }, - "peerDependencies": { - "twig": "1.x" + "engines": { + "node": ">=8.10.0" } }, - "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==", + "node_modules/vite-plugin-svg-sprite": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/vite-plugin-svg-sprite/-/vite-plugin-svg-sprite-0.7.0.tgz", + "integrity": "sha512-z3KNUVELZxFkDPLswR4ua7S29FMYkluGP1BdCX5PYBYMkFp/3jrlZpC9Fhu2LrkNH56AejFAOWHWR7+qxAP8Vw==", "license": "MIT", "dependencies": { - "prelude-ls": "^1.2.1" + "@xmldom/xmldom": "^0.9.4", + "micromatch": "^4.0.2", + "svgo": "^3.0.2" }, - "engines": { - "node": ">= 0.8.0" + "peerDependencies": { + "react": "17 || 18 || 19", + "vite": "2 || 3 || 4 || 5 || 6 || 7", + "vue": "3" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "vue": { + "optional": true + } } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "license": "(MIT OR CC0-1.0)", + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/typed-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", - "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", - "license": "MIT", + "node_modules/vituum": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vituum/-/vituum-1.2.0.tgz", + "integrity": "sha512-1YYOrzrIMSeWj6zAib5VTsNo1oDcqSg45jCFjxzU70vMPBONoXXhTAMcX0p21Bj7NkzceBFgdmEtnAze258lqw==", "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.14" + "chokidar": "^3.5", + "fast-glob": "^3.3", + "lodash": "^4.17", + "minimatch": "^10.0", + "vite": "^6.2" }, "engines": { - "node": ">= 0.4" + "node": "^18.0.0 || >=20.0.0" } }, - "node_modules/typed-query-selector": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.1.tgz", - "integrity": "sha512-uzR+FzI8qrUEIu96oaeBJmd9E7CFEiQ3goA5qCVgc4s5llSubcfGHq9yUstZx/k4s9dXHVKsE35YWoFyvEqEHA==", - "license": "MIT" + "node_modules/vituum/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "license": "Apache-2.0", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, + "node_modules/vituum/node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=14.17" + "node": ">=18" } }, - "node_modules/uglify-js": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "dev": true, - "license": "BSD-2-Clause", + "node_modules/vituum/node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, + "os": [ + "android" + ], "engines": { - "node": ">=0.8.0" + "node": ">=18" } }, - "node_modules/uint8array-extras": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", - "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", - "license": "MIT", + "node_modules/vituum/node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/un-eval": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/un-eval/-/un-eval-1.2.0.tgz", - "integrity": "sha512-Wlj/pum6dQtGTPD/lclDtoVPkSfpjPfy1dwnnKw/sZP5DpBH9fLhBgQfsqNhe5/gS1D+vkZUuB771NRMUPA5CA==", - "license": "MIT" + "node_modules/vituum/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "license": "MIT", - "dependencies": { - "buffer": "^5.2.1", - "through": "^2.3.8" + "node_modules/vituum/node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" } }, - "node_modules/unbzip2-stream/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } + "node_modules/vituum/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/undici": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.7.tgz", - "integrity": "sha512-H/nlJ/h0ggGC+uRL3ovD+G0i4bqhvsDOpbDv7At5eFLlj2b41L8QliGbnl2H7SnDiYhENphh1tQFJZf+MyfLsQ==", - "dev": true, - "license": "MIT", + "node_modules/vituum/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=20.18.1" + "node": ">=18" } }, - "node_modules/undici-types": { - "version": "7.19.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", - "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", - "license": "MIT" + "node_modules/vituum/node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", - "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", - "license": "MIT", + "node_modules/vituum/node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=4" + "node": ">=18" } }, - "node_modules/unicode-emoji-modifier-base": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", - "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", - "dev": true, - "license": "MIT", + "node_modules/vituum/node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=4" + "node": ">=18" } }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "license": "MIT", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, + "node_modules/vituum/node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=4" + "node": ">=18" } }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", - "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", - "license": "MIT", + "node_modules/vituum/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=4" + "node": ">=18" } }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", - "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", - "license": "MIT", + "node_modules/vituum/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=4" + "node": ">=18" } }, - "node_modules/unicorn-magic": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", - "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", - "dev": true, - "license": "MIT", + "node_modules/vituum/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/unique-string": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", - "license": "MIT", - "dependencies": { - "crypto-random-string": "^4.0.0" - }, + "node_modules/vituum/node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, - "node_modules/universal-user-agent": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", - "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==", - "dev": true, - "license": "ISC" - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "license": "MIT", + "node_modules/vituum/node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unrs-resolver": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", - "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "napi-postinstall": "^0.3.0" - }, - "funding": { - "url": "https://opencollective.com/unrs-resolver" - }, - "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.11.1", - "@unrs/resolver-binding-android-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-x64": "1.11.1", - "@unrs/resolver-binding-freebsd-x64": "1.11.1", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", - "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-musl": "1.11.1", - "@unrs/resolver-binding-wasm32-wasi": "1.11.1", - "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", - "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", - "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + "node": ">=18" } }, - "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", - "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" - } + "node_modules/vituum/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", - "license": "MIT" - }, - "node_modules/upper-case-first": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz", - "integrity": "sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==", - "license": "MIT", - "dependencies": { - "upper-case": "^1.1.1" + "node_modules/vituum/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" + "node_modules/vituum/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/uri-js/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", + "node_modules/vituum/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=6" + "node": ">=18" } }, - "node_modules/url": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", - "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", - "license": "MIT", - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.12.3" - }, + "node_modules/vituum/node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "openharmony" + ], "engines": { - "node": ">= 0.4" + "node": ">=18" } }, - "node_modules/url-join": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", - "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", - "dev": true, - "license": "MIT", + "node_modules/vituum/node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" } }, - "node_modules/url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==", - "license": "MIT", - "dependencies": { - "prepend-http": "^1.0.1" - }, + "node_modules/vituum/node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==", - "license": "MIT", + "node_modules/vituum/node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 4" + "node": ">=18" } }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" + "node_modules/vituum/node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, - "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==", - "license": "MIT" - }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", - "license": "MIT" - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" + "node_modules/vituum/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "engines": { + "node": "18 || 20 || >=22" } }, - "node_modules/v8-to-istanbul": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", - "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", - "license": "ISC", + "node_modules/vituum/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">=10.12.0" + "node": "18 || 20 || >=22" } }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "license": "Apache-2.0", + "node_modules/vituum/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "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/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==", - "license": "MIT", - "dependencies": { - "xml-name-validator": "^5.0.0" + "node_modules/vituum/node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" }, "engines": { "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" } }, - "node_modules/walk": { - "version": "2.3.15", - "resolved": "https://registry.npmjs.org/walk/-/walk-2.3.15.tgz", - "integrity": "sha512-4eRTBZljBfIISK1Vnt69Gvr2w/wc3U6Vtrw7qiN5iqYJPH7LElcYh/iU4XWhdCy2dZqv1ToMyYlybDylfG/5Vg==", - "license": "(MIT OR Apache-2.0)", - "dependencies": { - "foreachasync": "^3.0.0" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "license": "Apache-2.0", - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/watchpack": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", - "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", - "license": "MIT", + "node_modules/vituum/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/web-worker": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.5.0.tgz", - "integrity": "sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==", - "license": "Apache-2.0" - }, - "node_modules/webdriver-bidi-protocol": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.1.tgz", - "integrity": "sha512-ARrjNjtWRRs2w4Tk7nqrf2gBI0QXWuOmMCx2hU+1jUt6d00MjMxURrhxhGbrsoiZKJrhTSTzbIrc554iKI10qw==", - "license": "Apache-2.0" - }, - "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==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" + "node": ">= 6" } }, - "node_modules/webpack": { - "version": "5.106.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.106.1.tgz", - "integrity": "sha512-EW8af29ak8Oaf4T8k8YsajjrDBDYgnKZ5er6ljWFJsXABfTNowQfvHLftwcepVgdz+IoLSdEAbBiM9DFXoll9w==", - "license": "MIT", - "dependencies": { - "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.8", - "@types/json-schema": "^7.0.15", - "@webassemblyjs/ast": "^1.14.1", - "@webassemblyjs/wasm-edit": "^1.14.1", - "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.16.0", - "acorn-import-phases": "^1.0.3", - "browserslist": "^4.28.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.20.0", - "es-module-lexer": "^2.0.0", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.3.1", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^4.3.3", - "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.3.17", - "watchpack": "^2.5.1", - "webpack-sources": "^3.3.4" - }, - "bin": { - "webpack": "bin/webpack.js" + "node_modules/vituum/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dependencies": { + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=10.13.0" + "node": "18 || 20 || >=22" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/vituum/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } + "engines": { + "node": ">=8.10.0" } }, - "node_modules/webpack-cli": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-7.0.2.tgz", - "integrity": "sha512-dB0R4T+C/8YuvM+fabdvil6QE44/ChDXikV5lOOkrUeCkW5hTJv2pGLE3keh+D5hjYw8icBaJkZzpFoaHV4T+g==", - "license": "MIT", + "node_modules/vituum/node_modules/vite": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.2.tgz", + "integrity": "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==", "dependencies": { - "@discoveryjs/json-ext": "^1.0.0", - "commander": "^14.0.3", - "cross-spawn": "^7.0.6", - "envinfo": "^7.14.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^6.0.1" + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" }, "bin": { - "webpack-cli": "bin/cli.js" + "vite": "bin/vite.js" }, "engines": { - "node": ">=20.9.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" }, "peerDependencies": { - "webpack": "^5.101.0", - "webpack-bundle-analyzer": "^4.0.0 || ^5.0.0", - "webpack-dev-server": "^5.0.0" + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { - "webpack-bundle-analyzer": { + "@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 }, - "webpack-dev-server": { + "yaml": { "optional": true } } }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "14.0.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", - "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", - "license": "MIT", - "engines": { - "node": ">=20" - } - }, - "node_modules/webpack-dev-middleware": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.3.tgz", - "integrity": "sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw==", - "license": "MIT", - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.12", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, + "node_modules/vituum/node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "node": ">=12.0.0" }, "peerDependencies": { - "webpack": "^5.0.0" + "picomatch": "^3 || ^4" }, "peerDependenciesMeta": { - "webpack": { + "picomatch": { "optional": true } } }, - "node_modules/webpack-hot-middleware": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.26.1.tgz", - "integrity": "sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A==", - "license": "MIT", - "dependencies": { - "ansi-html-community": "0.0.8", - "html-entities": "^2.1.0", - "strip-ansi": "^6.0.0" + "node_modules/vituum/node_modules/vite/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/webpack-merge": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", - "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "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==", "license": "MIT", "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.1" + "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=18" } }, - "node_modules/webpack-remove-empty-scripts": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/webpack-remove-empty-scripts/-/webpack-remove-empty-scripts-1.1.1.tgz", - "integrity": "sha512-FqmIy7joxXd0/7jz8UjzMXOKc6B7LR+ynfgaaaH72xUT917h3A94ERxOLvGM8a8XdGIvUsdTLIUt8aBQM2Pdqg==", - "license": "ISC", + "node_modules/walk": { + "version": "2.3.15", + "resolved": "https://registry.npmjs.org/walk/-/walk-2.3.15.tgz", + "integrity": "sha512-4eRTBZljBfIISK1Vnt69Gvr2w/wc3U6Vtrw7qiN5iqYJPH7LElcYh/iU4XWhdCy2dZqv1ToMyYlybDylfG/5Vg==", + "license": "(MIT OR Apache-2.0)", "dependencies": { - "ansis": "4.0.0-node10" - }, - "engines": { - "node": ">=12.14" - }, - "funding": { - "type": "patreon", - "url": "https://patreon.com/biodiscus" - }, - "peerDependencies": { - "webpack": ">=5.32.0" + "foreachasync": "^3.0.0" } }, - "node_modules/webpack-sources": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.4.tgz", - "integrity": "sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==", - "license": "MIT", - "engines": { - "node": ">=10.13.0" + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" } }, - "node_modules/webpack-virtual-modules": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", - "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", - "license": "MIT" + "node_modules/web-worker": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.5.0.tgz", + "integrity": "sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==", + "dev": true, + "license": "Apache-2.0" }, - "node_modules/webpack/node_modules/es-module-lexer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", - "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", - "license": "MIT" + "node_modules/webdriver-bidi-protocol": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.1.tgz", + "integrity": "sha512-ARrjNjtWRRs2w4Tk7nqrf2gBI0QXWuOmMCx2hU+1jUt6d00MjMxURrhxhGbrsoiZKJrhTSTzbIrc554iKI10qw==", + "license": "Apache-2.0" }, - "node_modules/webpack/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "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==", "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, "engines": { - "node": ">=8.0.0" + "node": ">=12" } }, - "node_modules/webpack/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "license": "MIT" }, "node_modules/whatwg-encoding": { "version": "3.1.1", @@ -25131,12 +22093,69 @@ "node": ">= 8" } }, - "node_modules/which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true, - "license": "ISC" + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/which-typed-array": { "version": "1.1.20", @@ -25159,12 +22178,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "license": "MIT" - }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -25182,18 +22195,18 @@ "license": "MIT" }, "node_modules/wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-10.0.0.tgz", + "integrity": "sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" + "ansi-styles": "^6.2.3", + "string-width": "^8.2.0", + "strip-ansi": "^7.1.2" }, "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" @@ -25212,26 +22225,18 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "dev": true, - "license": "MIT" - }, "node_modules/wrap-ansi/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", + "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", "dev": true, "license": "MIT", "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" }, "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -25285,9 +22290,9 @@ } }, "node_modules/ws": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", - "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -25340,6 +22345,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.4" @@ -25361,9 +22367,9 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", - "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", "license": "ISC", "bin": { "yaml": "bin.mjs" @@ -25375,45 +22381,73 @@ "url": "https://github.com/sponsors/eemeli" } }, - "node_modules/yaml-loader": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/yaml-loader/-/yaml-loader-0.8.1.tgz", - "integrity": "sha512-BCEndnUoi3BaZmePkwGGe93txRxLgMhBa/gE725v1/GHnura8QvNs7c4+4C1yyhhKoj3Dg63M7IqhA++15j6ww==", - "license": "MIT", - "dependencies": { - "javascript-stringify": "^2.0.1", - "loader-utils": "^2.0.0", - "yaml": "^2.0.0" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "dev": true, "license": "MIT", "dependencies": { - "cliui": "^8.0.1", + "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", + "string-width": "^7.2.0", "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" + "yargs-parser": "^22.0.0" }, "engines": { - "node": ">=12" + "node": "^20.19.0 || ^22.12.0 || >=23" } }, "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, "engines": { "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/yauzl": { @@ -25442,6 +22476,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" diff --git a/package.json b/package.json index 4a22226..fb5fdd3 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,18 @@ { "name": "@emulsify/core", - "version": "3.5.0", - "description": "Bundled tooling for Storybook development + Webpack Build", + "version": "4.0.0", + "description": "Bundled tooling for Storybook development + Vite Build", "keywords": [ "component library", + "craftcms", "design system", "drupal", "pattern library", "storybook", - "styleguide" + "styleguide", + "twig", + "vite", + "wordpress" ], "author": "Four Kitchens ", "license": "GPL-2.0", @@ -16,6 +20,10 @@ "node": ">=24" }, "type": "module", + "bin": { + "emulsify-audit": "./scripts/audit.js", + "emulsify-audit-twig-stories": "./scripts/audit-twig-stories.js" + }, "repository": { "type": "git", "url": "git+https://github.com/emulsify-ds/emulsify-core.git" @@ -24,6 +32,86 @@ "url": "https://github.com/emulsify-ds/emulsify-core/issues" }, "homepage": "https://github.com/emulsify-ds/emulsify-core#readme", + "files": [ + ".cli/init.js", + ".storybook/_drupal.js", + ".storybook/emulsifyTheme.js", + ".storybook/main.js", + ".storybook/manager.js", + ".storybook/preview.js", + ".storybook/utils.js", + "assets/**/*", + "config/.prettierrc.json", + "config/.stylelintrc.json", + "config/a11y.config.js", + "config/babel.config.js", + "config/eslint.config.js", + "config/jest.config.js", + "config/postcss.config.js", + "config/vite/entries.js", + "config/vite/environment.js", + "config/vite/platforms.js", + "config/vite/plugins/copy-src-assets.js", + "config/vite/plugins/copy-twig-files.js", + "config/vite/plugins/css-asset-relativizer.js", + "config/vite/plugins/index.js", + "config/vite/plugins/mirror-components.js", + "config/vite/plugins/source-file-index.js", + "config/vite/plugins/svg-sprite.js", + "config/vite/plugins/twig-module.js", + "config/vite/plugins/virtual-twig-globs.js", + "config/vite/plugins/vituum-patch.js", + "config/vite/plugins/yaml-module.js", + "config/vite/plugins.js", + "config/vite/project-config.js", + "config/vite/project-extensions.js", + "config/vite/project-structure.js", + "config/vite/test-utils/virtual-twig-globs.js", + "config/vite/utils/fs-safe.js", + "config/vite/utils/paths.js", + "config/vite/utils/react-singleton.js", + "config/vite/utils/unique.js", + "config/vite/vite.config.js", + "docs/**/*", + "scripts/a11y.js", + "scripts/audit.js", + "scripts/audit-twig-stories.js", + "scripts/check-node-version.js", + "scripts/loadYaml.js", + "src/extensions/index.js", + "src/extensions/react/index.js", + "src/extensions/react/register.js", + "src/extensions/shared/attributes.js", + "src/extensions/shared/html.js", + "src/extensions/shared/lists.js", + "src/extensions/shared/object.js", + "src/extensions/twig/function-map.js", + "src/extensions/twig/functions/add-attributes.js", + "src/extensions/twig/functions/bem.js", + "src/extensions/twig/index.js", + "src/extensions/twig/register.js", + "src/extensions/twig/tag-map.js", + "src/extensions/twig/tags/switch.js", + "src/storybook/index.js", + "src/storybook/main-config.js", + "src/storybook/platform-behaviors.js", + "src/storybook/preview-parameters.js", + "src/storybook/render-twig.js", + "src/storybook/twig/include.js", + "src/storybook/twig/resolver.js", + "src/storybook/twig/setup.js", + "src/storybook/twig/source.js" + ], + "exports": { + ".": "./src/extensions/index.js", + "./extensions": "./src/extensions/index.js", + "./extensions/react": "./src/extensions/react/index.js", + "./extensions/twig": "./src/extensions/twig/index.js", + "./storybook": "./src/storybook/index.js", + "./vite": "./config/vite/vite.config.js", + "./vite/plugins": "./config/vite/plugins.js", + "./package.json": "./package.json" + }, "publishConfig": { "access": "public" }, @@ -31,113 +119,100 @@ "scripts-prepend-node-path": "auto" }, "scripts": { - "coverage": "npm run test && open-cli .coverage/lcov-report/index.html", - "format": "npm run lint-fix; npm run prettier-fix", - "husky:commit-msg": "commitlint --edit $1", - "husky:pre-commit": "npm run lint", - "lint": "npm run lint-js", - "lint-fix": "npm run lint-js -- --fix", - "lint-js": "eslint --config config/eslint.config.js --no-error-on-unmatched-pattern ./config ./.storybook", - "lint-staged": "lint-staged", - "prepare": "[ -d '.git' ] && (husky install) || true", - "prettier": "prettier --config config/prettierrc.json --ignore-unknown \"**/*.{js,yml,scss,md}\"", - "prettier-fix": "prettier --config config/prettierrc.json --write --ignore-unknown \"**/*.{js,yml,scss,md}\"", - "semantic-release": "semantic-release --config ./release.config.cjs", - "storybook": "NODE_OPTIONS=--no-deprecation storybook dev --ci -p 6006", - "storybook-build": "storybook build -o .out", - "storybook-deploy": "storybook-to-ghpages -o .out", - "test": "jest --coverage --config ./config/jest.config.js", - "twatch": "jest --no-coverage --watch --verbose" + "check-node-version": "node scripts/check-node-version.js", + "audit": "npm run check-node-version && node scripts/audit.js", + "audit:twig-stories": "npm run check-node-version && node scripts/audit-twig-stories.js", + "coverage": "npm run check-node-version && npm run test && open-cli .coverage/lcov-report/index.html", + "format": "npm run check-node-version && npm run lint-fix && npm run prettier-fix", + "fixtures:release": "npm run check-node-version && node scripts/release-fixtures.js", + "fixtures:release:list": "npm run check-node-version && node scripts/release-fixtures.js --list", + "husky:commit-msg": "npm run check-node-version && commitlint --edit $1", + "husky:pre-commit": "npm run check-node-version && npm run lint", + "lint": "npm run check-node-version && npm run lint-js", + "lint-fix": "npm run check-node-version && npm run lint-js -- --fix", + "lint-js": "npm run check-node-version && eslint --config config/eslint.config.js --no-error-on-unmatched-pattern ./config ./storybook ./src", + "lint-staged": "npm run check-node-version && lint-staged", + "prepare": "npm run check-node-version && husky", + "prettier": "npm run check-node-version && prettier --config config/.prettierrc.json --ignore-unknown \"**/*.{js,yml,scss,md}\"", + "prettier-fix": "npm run check-node-version && prettier --config config/.prettierrc.json --write --ignore-unknown \"**/*.{js,yml,scss,md}\"", + "semantic-release": "npm run check-node-version && semantic-release --config ./release.config.cjs", + "version:develop": "npm run check-node-version && node scripts/bump-version-from-commits.js", + "storybook": "npm run check-node-version && NODE_OPTIONS=--no-deprecation storybook dev -p 6006 --no-open --exact-port", + "storybook-build": "npm run check-node-version && storybook build -o .out", + "storybook-deploy": "npm run check-node-version && storybook-to-ghpages -o .out", + "test": "npm run check-node-version && jest --coverage --config ./config/jest.config.js", + "twatch": "npm run check-node-version && jest --no-coverage --watch --verbose" }, "dependencies": { - "@babel/core": "^7.28.5", - "@babel/preset-env": "^7.28.5", + "@babel/core": "^7.28.4", + "@babel/eslint-parser": "^7.28.6", + "@babel/preset-env": "^7.28.3", "@emulsify/cli": "^1.11.4", - "@eslint/js": "^10.0.1", - "@storybook/addon-a11y": "^9.1.20", - "@storybook/addon-links": "^9.1.20", - "@storybook/addon-styling-webpack": "^2.0.0", - "@storybook/addon-themes": "^9.1.20", - "@storybook/builder-webpack5": "^9.1.20", - "@storybook/server-webpack5": "^9.1.20", - "add-attributes-twig-extension": "^0.1.0", + "@eslint/js": "^9.39.4", + "@storybook/addon-a11y": "^10.1.4", + "@storybook/addon-links": "^10.1.4", + "@storybook/addon-themes": "^10.1.4", + "@storybook/react": "^10.1.4", + "@storybook/react-vite": "^10.1.4", + "@vituum/vite-plugin-twig": "^1.1.0", "autoprefixer": "^10.4.21", - "babel-loader": "^10.0.0", "babel-preset-minify": "^0.5.2", - "bem-twig-extension": "^0.1.1", - "breakpoint-sass": "^3.0.0", - "clean-webpack-plugin": "^4.0.0", "concurrently": "^9.2.1", - "copy-webpack-plugin": "^14.0.0", - "css-loader": "^7.1.1", - "eslint": "^10.1.0", + "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", - "eslint-plugin-jest": "^29.15.1", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-jest": "^29.0.1", "eslint-plugin-prettier": "^5.5.4", "eslint-plugin-security": "^4.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^11.3.2", + "eslint-plugin-storybook": "^10.1.4", + "fs-extra": "^11.3.1", "glob": "^13.0.6", "graceful-fs": "^4.2.11", - "html-webpack-plugin": "^5.6.4", - "image-minimizer-webpack-plugin": "^5.0.0", - "imagemin": "^9.0.1", - "imagemin-jpegtran": "^8.0.0", - "imagemin-optipng": "^8.0.0", "jest": "^30.2.0", "jest-environment-jsdom": "^30.2.0", "js-yaml": "^4.1.0", - "js-yaml-loader": "^1.2.2", - "mini-css-extract-plugin": "^2.9.4", - "node-sass-glob-importer": "^5.3.3", "normalize.css": "^8.0.1", "open-cli": "^9.0.0", "pa11y": "^9.0.1", - "postcss": "^8.5.6", - "postcss-loader": "^8.2.0", + "postcss": "^8.5.4", "postcss-scss": "^4.0.9", "ramda": "^0.32.0", "regenerator-runtime": "^0.14.1", "sass": "^1.93.2", - "sass-loader": "^16.0.6", - "storybook": "^9.1.20", - "style-dictionary": "^5.1.1", - "stylelint": "^17.7.0", + "storybook": "^10.1.4", + "stylelint": "^17.12.0", "stylelint-config-standard-scss": "^17.0.0", "stylelint-prettier": "^5.0.3", - "stylelint-webpack-plugin": "^5.0.1", - "svg-spritemap-webpack-plugin": "^5.0.3", - "terser-webpack-plugin": "^5.3.9", - "token-transformer": "^0.0.33", + "stylelint-selector-bem-pattern": "^5.0.0", + "twig": "^3.0.0", "twig-drupal-filters": "^3.2.0", - "twig-testing-library": "^1.2.0", - "twigjs-loader": "^1.0.3", - "webpack": "^5.102.1", - "webpack-cli": "^7.0.2", - "webpack-merge": "^6.0.1", - "webpack-remove-empty-scripts": "^1.1.1", + "vite": "^7.3.3", + "vite-plugin-sass-glob-import": "^6.0.0", + "vite-plugin-static-copy": "^4.1.0", + "vite-plugin-svg-sprite": "^0.7.0", "yaml": "^2.8.1" }, "devDependencies": { - "@commitlint/cli": "^20.1.0", - "@commitlint/config-conventional": "^20.0.0", + "@commitlint/cli": "^21.0.1", + "@commitlint/config-conventional": "^21.0.1", "@semantic-release/changelog": "^6.0.2", "@semantic-release/commit-analyzer": "^13.0.1", "@semantic-release/git": "^10.0.1", - "@semantic-release/github": "^12.0.6", + "@semantic-release/github": "^12.0.8", "@semantic-release/release-notes-generator": "^14.1.0", - "all-contributors-cli": "^6.26.1", "husky": "^9.1.7", - "lint-staged": "^16.2.6", + "lint-staged": "^17.0.5", + "react": "^19.2.0", + "react-dom": "^19.2.0", "semantic-release": "^25.0.3" }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, "overrides": { - "inflight": "^1.0.7", - "graceful-fs": "^4.2.11", "glob": "^13.0.6", - "rimraf": "^4.3.0", - "source-map-url": "^0.4.1", - "source-map-resolve": "^0.6.0", - "uuid": "^8.3.2" + "locutus": "^3.0.36", + "minimatch@3.0.x": "^3.1.5" } } diff --git a/release.config.cjs b/release.config.cjs index 32b9be7..170e473 100644 --- a/release.config.cjs +++ b/release.config.cjs @@ -1,30 +1,34 @@ -// release.config.cjs +/** + * @file Semantic Release configuration. + */ + module.exports = { branches: ['main'], repositoryUrl: 'git@github.com:emulsify-ds/emulsify-core.git', plugins: [ + // Conventional commit analysis determines the next release version. [ '@semantic-release/commit-analyzer', { preset: 'angular', parserOpts: { - noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES', 'BREAKING'] - } - } + noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES', 'BREAKING'], + }, + }, ], [ '@semantic-release/release-notes-generator', { preset: 'angular', parserOpts: { - noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES', 'BREAKING'] + noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES', 'BREAKING'], }, writerOpts: { - commitsSort: ['subject', 'scope'] - } - } + commitsSort: ['subject', 'scope'], + }, + }, ], ['@semantic-release/npm', { npmPublish: true }], - '@semantic-release/github' - ] -} + '@semantic-release/github', + ], +}; diff --git a/scripts/a11y.js b/scripts/a11y.js index fc3891e..c23d0c9 100755 --- a/scripts/a11y.js +++ b/scripts/a11y.js @@ -56,7 +56,8 @@ const severityToColor = R.cond([ const issueIsValid = (issue) => { const code = issue?.code; const description = issue?.runnerExtras?.description; - const codeIgnored = Array.isArray(ignore?.codes) && ignore.codes.includes(code); + const codeIgnored = + Array.isArray(ignore?.codes) && ignore.codes.includes(code); const descIgnored = description && Array.isArray(ignore?.descriptions) && @@ -138,7 +139,6 @@ const lintReportAndExit = R.pipe( // Only perform linting/reporting when instructed via "-r". /* istanbul ignore next */ if (R.pathEq(['argv', 2], '-r')(process)) { - // eslint-disable-next-line promise/catch-or-return lintReportAndExit(components); } diff --git a/scripts/a11y.test.js b/scripts/a11y.test.js index 0abc83a..5193962 100644 --- a/scripts/a11y.test.js +++ b/scripts/a11y.test.js @@ -1,9 +1,24 @@ +/** + * @file Unit tests for the pa11y accessibility reporting script. + */ + import 'regenerator-runtime/runtime'; const mockExit = jest .spyOn(global.process, 'exit') .mockImplementation(() => {}); jest.mock('pa11y', () => jest.fn()); +jest.mock( + '../../../config/emulsify-core/a11y.config.js', + () => ({ + components: [], + ignore: { + codes: ['landmark-one-main', 'page-has-heading-one'], + descriptions: ['Ensures all page content is contained by landmarks'], + }, + }), + { virtual: true }, +); jest.spyOn(global.console, 'log').mockImplementation(() => {}); const pa11y = require('pa11y'); const path = require('path'); @@ -28,12 +43,11 @@ pa11y.mockResolvedValue('very official report'); describe('a11y', () => { beforeEach(() => { + // Reset mocked process and console state between report scenarios. global.console.log.mockClear(); global.process.exit.mockClear(); }); - - it('maps axe issue severity to a label', () => { - // (Name no longer mentions "chalk") + it('can map axe issue severity to the correct chalk color', () => { expect.assertions(3); expect(severityToColor('error')).toBe('red'); expect(severityToColor('warning')).toBe('yellow'); @@ -58,7 +72,7 @@ describe('a11y', () => { expect(issueIsValid({ code: 'chicken', runnerExtras: {} })).toBe(true); }); - it('logs a single issue without color codes', () => { + it('can use an axe issue to generate a single log message about the issue', () => { expect.assertions(1); logIssue({ type: 'error', @@ -67,16 +81,16 @@ describe('a11y', () => { selector: 'kfc > popeyes > .chicken', }); expect(global.console.log.mock.calls[0][0]).toMatchInlineSnapshot(` -" -severity: error -message: this chicken is not fried enough. -context: https://example.com -selector: kfc > popeyes > .chicken -" -`); + " + severity: error + message: this chicken is not fried enough. + context: https://example.com + selector: kfc > popeyes > .chicken + " + `); }); - it('logs a whole report without color codes', () => { + it('can log a whole axe report', () => { const report = { issues: [ { @@ -98,56 +112,45 @@ selector: kfc > popeyes > .chicken }; expect(logReport(report)).toBe(true); expect(global.console.log.mock.calls).toMatchInlineSnapshot(` -Array [ - Array [ - "Issues found in component: https://example/component.html", - ], - Array [ - " -severity: error -message: this pizza is too soggy -context: https://example.com -selector: pizza > .hut -", - ], - Array [ - " -severity: error -message: this pasta is undercooked -context: https://example.com -selector: olive > .garden -", - ], -] -`); + [ + [ + "Issues found in component: https://example/component.html", + ], + [ + " + severity: error + message: this pizza is too soggy + context: https://example.com + selector: pizza > .hut + ", + ], + [ + " + severity: error + message: this pasta is undercooked + context: https://example.com + selector: olive > .garden + ", + ], + ] + `); }); - it('logs that a component has no issues when a report is empty', () => { + it('logs about a component having no issue if a report comes back empty', () => { expect(logReport({ issues: [], pageUrl: 'papa-johns' })).toBe(false); expect(global.console.log.mock.calls[0][0]).toMatchInlineSnapshot( - `"No issues found in component: papa-johns"`, + '"No issues found in component: papa-johns"', ); }); - it('calls pa11y with the full path to a component', async () => { - expect.assertions(3); + it('can call pa11y with the full path to a component', async () => { + expect.assertions(2); await expect(lintComponent('chicken-strips')).resolves.toBe( 'very official report', ); - - // First arg: URL - expect(pa11y.mock.calls[0][0]).toBe( + expect(pa11y).toHaveBeenCalledWith( `${STORYBOOK_IFRAME}?id=chicken-strips`, - ); - - // Second arg: options merged with defaults in a11y.js - expect(pa11y.mock.calls[0][1]).toEqual( - expect.objectContaining({ - includeNotices: true, - includeWarnings: true, - runners: ['axe'], - ...pa11yConfig, - }), + pa11yConfig, ); }); diff --git a/scripts/audit-twig-stories.js b/scripts/audit-twig-stories.js new file mode 100755 index 0000000..bb07aba --- /dev/null +++ b/scripts/audit-twig-stories.js @@ -0,0 +1,378 @@ +#!/usr/bin/env node + +/** + * @file Report legacy Twig Storybook stories that should migrate to renderTwig(). + */ + +import { existsSync, readFileSync } from 'node:fs'; +import { relative, resolve } from 'node:path'; +import { globSync } from 'glob'; +import { resolveProjectConfig } from '../config/vite/project-config.js'; +import { toPosixPath } from '../config/vite/utils/paths.js'; + +const STORY_GLOB = '**/*.stories.{js,jsx,ts,tsx}'; +const IDENTIFIER_PATTERN = '[A-Za-z_$][\\w$]*'; +const DEFAULT_IGNORES = [ + '**/node_modules/**', + '**/dist/**', + '**/.out/**', + '**/.coverage/**', +]; + +/** + * Escape a string for use inside a regular expression. + * + * @param {string} value - Raw string. + * @returns {string} Escaped string. + */ +function escapeRegExp(value) { + return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +} + +/** + * Find the 1-based line number for a character index. + * + * @param {string} source - File source. + * @param {number} index - Character index. + * @returns {number} 1-based line number. + */ +function lineNumberAt(source, index) { + return source.slice(0, index).split('\n').length; +} + +/** + * Find imported Twig template identifiers. + * + * @param {string} source - Story source. + * @returns {{name: string, specifier: string, line: number}[]} Twig imports. + */ +export function findTwigImports(source) { + const imports = []; + const patterns = [ + new RegExp( + `import\\s+(${IDENTIFIER_PATTERN})\\s+from\\s+['"]([^'"]+\\.twig(?:\\?[^'"]*)?)['"]`, + 'g', + ), + new RegExp( + `(?:const|let|var)\\s+(${IDENTIFIER_PATTERN})\\s*=\\s*require\\(\\s*['"]([^'"]+\\.twig(?:\\?[^'"]*)?)['"]\\s*\\)`, + 'g', + ), + ]; + + for (const pattern of patterns) { + for (const match of source.matchAll(pattern)) { + imports.push({ + name: match[1], + specifier: match[2], + line: lineNumberAt(source, match.index || 0), + }); + } + } + + return imports; +} + +/** + * Determine whether a story imports renderTwig from Emulsify Core. + * + * @param {string} source - Story source. + * @returns {boolean} TRUE when renderTwig is imported from the public helper. + */ +export function importsRenderTwig(source) { + return ( + /\brenderTwig\b/.test(source) && + /from\s+['"]@emulsify\/core\/storybook['"]/.test(source) + ); +} + +/** + * Find likely direct returns of imported Twig template functions. + * + * @param {string} source - Story source. + * @param {string[]} templateNames - Imported Twig template identifiers. + * @returns {{name: string, line: number}[]} Direct template calls. + */ +export function findDirectTemplateReturns(source, templateNames = []) { + const calls = []; + + for (const templateName of templateNames) { + const pattern = new RegExp( + `(?:return\\s+|=>\\s*(?:\\(\\s*)?)${escapeRegExp(templateName)}\\s*\\(`, + 'g', + ); + + for (const match of source.matchAll(pattern)) { + calls.push({ + name: templateName, + line: lineNumberAt(source, match.index || 0), + }); + } + } + + return calls; +} + +/** + * Analyze one Storybook story source string. + * + * @param {string} source - Story source. + * @param {string} [filePath=''] - Story file path. + * @returns {object} Story analysis. + */ +export function analyzeStorySource(source, filePath = '') { + const twigImports = findTwigImports(source); + const templateNames = twigImports.map((item) => item.name); + const hasRenderTwig = importsRenderTwig(source); + const directTemplateReturns = findDirectTemplateReturns( + source, + templateNames, + ); + const reasons = []; + + if (!twigImports.length) { + return { + filePath, + twigImports, + hasRenderTwig, + directTemplateReturns, + reasons, + shouldUpgrade: false, + }; + } + + if (!hasRenderTwig) { + reasons.push('imports Twig templates without renderTwig()'); + } + + if (directTemplateReturns.length) { + reasons.push('appears to return Twig HTML strings directly'); + } + + return { + filePath, + twigImports, + hasRenderTwig, + directTemplateReturns, + reasons, + shouldUpgrade: reasons.length > 0, + }; +} + +/** + * Resolve Storybook source roots for the project. + * + * @param {string} projectDir - Absolute project root. + * @returns {string[]} Absolute story roots. + */ +export function resolveStoryRoots(projectDir) { + try { + const env = resolveProjectConfig(projectDir, process.env); + const storyRoots = env.projectStructure?.storyRoots; + if (Array.isArray(storyRoots) && storyRoots.length) { + return storyRoots; + } + } catch { + // Fall back to conventional roots when project config is absent or invalid. + } + + return [resolve(projectDir, 'src'), resolve(projectDir, 'components')]; +} + +/** + * Collect Storybook story files from normalized project roots. + * + * @param {string} projectDir - Absolute project root. + * @returns {string[]} Absolute story file paths. + */ +export function collectStoryFiles(projectDir) { + const files = new Set(); + + for (const root of resolveStoryRoots(projectDir)) { + if (!existsSync(root)) continue; + + for (const match of globSync(STORY_GLOB, { + cwd: root, + nodir: true, + absolute: true, + ignore: DEFAULT_IGNORES, + })) { + files.add(resolve(match)); + } + } + + return Array.from(files).sort(); +} + +/** + * Analyze all discovered story files in a project. + * + * @param {{projectDir?: string}} [options={}] - Audit options. + * @returns {{projectDir: string, files: string[], findings: object[]}} Results. + */ +export function auditTwigStories(options = {}) { + const projectDir = resolve(options.projectDir || process.cwd()); + const files = collectStoryFiles(projectDir); + const findings = files + .map((filePath) => { + const source = readFileSync(filePath, 'utf8'); + return analyzeStorySource(source, filePath); + }) + .filter((result) => result.shouldUpgrade); + + return { + projectDir, + files, + findings, + }; +} + +/** + * Format audit findings for terminal output. + * + * @param {{projectDir: string, files: string[], findings: object[]}} result + * Audit result. + * @returns {string} Human-readable report. + */ +export function formatAuditReport(result) { + const lines = [ + 'Twig story migration audit', + `Scanned ${result.files.length} story file(s).`, + ]; + + if (!result.findings.length) { + lines.push('No legacy Twig story candidates found.'); + return lines.join('\n'); + } + + lines.push( + `Found ${result.findings.length} story file(s) that should be reviewed:`, + ); + + for (const finding of result.findings) { + const relPath = toPosixPath(relative(result.projectDir, finding.filePath)); + const importNames = finding.twigImports.map((item) => item.name).join(', '); + + lines.push('', `- ${relPath}`); + lines.push(` Twig imports: ${importNames}`); + for (const reason of finding.reasons) { + lines.push(` Reason: ${reason}.`); + } + for (const call of finding.directTemplateReturns) { + lines.push( + ` Line ${call.line}: ${call.name}() appears to be returned directly.`, + ); + } + } + + lines.push( + '', + 'Suggested migration: import { renderTwig } from "@emulsify/core/storybook" and move any argument mapping into renderTwig(template, { context }).', + ); + + return lines.join('\n'); +} + +/** + * Parse command-line arguments. + * + * @param {string[]} argv - CLI arguments. + * @returns {{projectDir: string, failOnFound: boolean, json: boolean, help: boolean}} + * Parsed options. + */ +function parseArgs(argv) { + const options = { + projectDir: process.cwd(), + failOnFound: false, + json: false, + help: false, + }; + + for (let index = 0; index < argv.length; index += 1) { + const arg = argv[index]; + + if (arg === '--help' || arg === '-h') { + options.help = true; + continue; + } + if (arg === '--fail-on-found') { + options.failOnFound = true; + continue; + } + if (arg === '--json') { + options.json = true; + continue; + } + if (arg === '--root') { + const value = argv[index + 1]; + if (!value || value.startsWith('--')) { + throw new Error('--root requires a project directory.'); + } + options.projectDir = value; + index += 1; + continue; + } + if (arg.startsWith('--root=')) { + options.projectDir = arg.slice('--root='.length); + continue; + } + + throw new Error(`Unknown option: ${arg}`); + } + + return options; +} + +/** + * CLI usage text. + * + * @returns {string} Usage text. + */ +function usage() { + return [ + 'Usage: emulsify-audit-twig-stories [--root ] [--json] [--fail-on-found]', + '', + 'Options:', + ' --root Project root to scan. Defaults to the current directory.', + ' --json Print machine-readable JSON.', + ' --fail-on-found Exit with code 1 when migration candidates are found.', + ' --help Print this help text.', + ].join('\n'); +} + +/** + * Run the CLI. + * + * @param {string[]} argv - CLI arguments. + * @returns {number} Process exit code. + */ +export function runCli(argv = process.argv.slice(2)) { + const options = parseArgs(argv); + + if (options.help) { + console.log(usage()); + return 0; + } + + const result = auditTwigStories({ + projectDir: options.projectDir, + }); + + if (options.json) { + console.log(JSON.stringify(result, null, 2)); + } else { + console.log(formatAuditReport(result)); + } + + return options.failOnFound && result.findings.length ? 1 : 0; +} + +if (process.argv[1]?.split(/[\\/]/).pop() === 'audit-twig-stories.js') { + try { + process.exitCode = runCli(); + } catch (error) { + console.error(error.message || error); + console.error(''); + console.error(usage()); + process.exitCode = 1; + } +} diff --git a/scripts/audit-twig-stories.test.js b/scripts/audit-twig-stories.test.js new file mode 100644 index 0000000..7f7b883 --- /dev/null +++ b/scripts/audit-twig-stories.test.js @@ -0,0 +1,91 @@ +/** + * @file Tests for the Twig story migration audit. + */ + +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { + analyzeStorySource, + auditTwigStories, + formatAuditReport, +} from './audit-twig-stories.js'; + +describe('audit-twig-stories', () => { + let projectDir; + + beforeEach(() => { + projectDir = mkdtempSync(join(tmpdir(), 'emulsify-twig-audit-')); + }); + + afterEach(() => { + rmSync(projectDir, { recursive: true, force: true }); + }); + + it('reports legacy stories that return imported Twig templates directly', () => { + const source = ` + import accordionTwig from './accordion.twig'; + + export const Accordion = ({ heading }) => + accordionTwig({ + accordion__heading: heading, + }); + `; + + const result = analyzeStorySource(source, 'accordion.stories.js'); + + expect(result.shouldUpgrade).toBe(true); + expect(result.twigImports).toEqual([ + { + name: 'accordionTwig', + specifier: './accordion.twig', + line: 2, + }, + ]); + expect(result.directTemplateReturns).toEqual([ + { + name: 'accordionTwig', + line: 4, + }, + ]); + expect(result.reasons).toContain( + 'imports Twig templates without renderTwig()', + ); + }); + + it('does not report stories that already use renderTwig', () => { + const source = ` + import template from './card.twig'; + import { renderTwig } from '@emulsify/core/storybook'; + + export default { + title: 'Components/Card', + render: renderTwig(template), + }; + + export const Default = {}; + `; + + expect(analyzeStorySource(source).shouldUpgrade).toBe(false); + }); + + it('scans project story roots and formats a readable report', () => { + const componentDir = join(projectDir, 'src/components/card'); + mkdirSync(componentDir, { recursive: true }); + writeFileSync( + join(componentDir, 'card.stories.js'), + ` + import cardTwig from './card.twig'; + + export const Card = (args) => cardTwig(args); + `, + ); + + const result = auditTwigStories({ projectDir }); + const report = formatAuditReport(result); + + expect(result.findings).toHaveLength(1); + expect(report).toContain('src/components/card/card.stories.js'); + expect(report).toContain('cardTwig() appears to be returned directly'); + }); +}); diff --git a/scripts/audit.js b/scripts/audit.js new file mode 100755 index 0000000..89ebd61 --- /dev/null +++ b/scripts/audit.js @@ -0,0 +1,1453 @@ +#!/usr/bin/env node + +/** + * @file Combined Emulsify project readiness audit. + */ + +import { lstatSync, readdirSync, statSync } from 'node:fs'; +import { basename, dirname, relative, resolve, sep } from 'node:path'; +import { globSync } from 'glob'; +import { resolveProjectConfig } from '../config/vite/project-config.js'; +import { + compiledAssetOutputPath, + storybookStyleOutputPath, +} from '../config/vite/project-structure.js'; +import { + firstExistingPath, + safeExists, + safeReadFile, + safeReadJson, +} from '../config/vite/utils/fs-safe.js'; +import { toPosixPath } from '../config/vite/utils/paths.js'; +import { candidateKeysForReference } from '../src/storybook/twig/resolver.js'; +import { analyzeStorySource, collectStoryFiles } from './audit-twig-stories.js'; + +const STORY_GLOB = '**/*.stories.{js,jsx,ts,tsx}'; +const CODE_GLOB = '**/*.{js,jsx,ts,tsx,mjs,cjs}'; +const TWIG_GLOB = '**/*.twig'; +const STYLE_GLOB = '**/*.{css,scss,sass}'; +const DEFAULT_IGNORES = [ + '**/.coverage/**', + '**/.git/**', + '**/.github/**', + '**/.out/**', + '**/dist/**', + '**/*.min.css', + '**/*.test.{js,jsx,ts,tsx,mjs,cjs}', + '**/node_modules/**', + '**/scripts/audit.js', + '**/vendor/**', +]; +const PUBLIC_CORE_IMPORTS = new Set([ + '@emulsify/core', + '@emulsify/core/extensions', + '@emulsify/core/extensions/react', + '@emulsify/core/extensions/twig', + '@emulsify/core/package.json', + '@emulsify/core/storybook', + '@emulsify/core/vite', + '@emulsify/core/vite/plugins', +]); +const DEFAULT_TWIG_THRESHOLD = 250; +const RECOMMENDED_PACKAGE_OVERRIDES = [ + { + label: 'glob', + value: '^13.0.6', + paths: [['glob']], + }, + { + label: 'locutus', + value: '^3.0.36', + paths: [['locutus']], + }, + { + label: 'minimatch@3.0.x', + value: '^3.1.5', + paths: [['minimatch@3.0.x']], + }, +]; + +/** + * Return a project-relative path for report output. + * + * @param {string} projectDir - Absolute project root. + * @param {string} filePath - Absolute file path. + * @returns {string} Project-relative POSIX path. + */ +function displayPath(projectDir, filePath) { + return toPosixPath(relative(projectDir, filePath)); +} + +/** + * Determine whether a candidate is a directory. + * + * @param {string} filePath - Absolute path. + * @returns {boolean} TRUE when the path is a directory. + */ +function safeIsDirectory(filePath) { + try { + return lstatSync(filePath).isDirectory(); + } catch { + return false; + } +} + +/** + * Find the 1-based line number for a character index. + * + * @param {string} source - File source. + * @param {number} index - Character index. + * @returns {number} 1-based line number. + */ +function lineNumberAt(source, index) { + return source.slice(0, index).split('\n').length; +} + +/** + * Build a report finding. + * + * @param {object} finding - Finding details. + * @returns {object} Normalized finding. + */ +function makeFinding(finding) { + return { + severity: 'warn', + docs: undefined, + ...finding, + }; +} + +/** + * Collect files from a project. + * + * @param {string} projectDir - Absolute project root. + * @param {string|string[]} patterns - Glob pattern or patterns. + * @returns {string[]} Absolute file paths. + */ +export function collectProjectFiles(projectDir, patterns) { + return globSync(patterns, { + cwd: projectDir, + nodir: true, + absolute: true, + ignore: DEFAULT_IGNORES, + }) + .map((filePath) => resolve(filePath)) + .sort(); +} + +/** + * Return a normalized, project-contained root list. + * + * @param {string} projectDir - Absolute project root. + * @param {string[]} roots - Absolute candidate roots. + * @returns {string[]} Existing roots inside the project. + */ +function normalizeAuditRoots(projectDir, roots = []) { + const resolvedProject = resolve(projectDir); + + return Array.from( + new Set( + roots + .filter(Boolean) + .map((root) => resolve(root)) + .filter( + (root) => + isSameOrInside(root, resolvedProject) && safeIsDirectory(root), + ), + ), + ).sort(); +} + +/** + * Collect files from normalized audit roots only. + * + * @param {string} projectDir - Absolute project root. + * @param {string|string[]} patterns - Glob pattern or patterns. + * @param {string[]} roots - Absolute roots to scan. + * @returns {string[]} Absolute file paths. + */ +function collectRootedProjectFiles(projectDir, patterns, roots = []) { + const files = new Set(); + + for (const root of normalizeAuditRoots(projectDir, roots)) { + for (const filePath of globSync(patterns, { + cwd: root, + nodir: true, + absolute: true, + ignore: DEFAULT_IGNORES, + })) { + files.add(resolve(filePath)); + } + } + + return Array.from(files).sort(); +} + +/** + * Determine whether a file is inside one of the roots. + * + * @param {string} filePath - Absolute file path. + * @param {string[]} roots - Absolute roots. + * @returns {boolean} TRUE when inside a root. + */ +function isInsideAnyRoot(filePath, roots = []) { + return roots.some((root) => { + const rel = relative(root, filePath); + return Boolean(rel) && !rel.startsWith('..') && !rel.includes(`..${sep}`); + }); +} + +/** + * Determine whether a path is the same as, or inside, a root directory. + * + * @param {string} filePath - Absolute file path. + * @param {string} root - Absolute root path. + * @returns {boolean} TRUE when the path is inside or equal to the root. + */ +function isSameOrInside(filePath, root) { + const rel = relative(root, filePath); + return !rel || (!rel.startsWith('..') && !rel.includes(`..${sep}`)); +} + +/** + * Return a nested object value. + * + * @param {object} obj - Object to inspect. + * @param {string[]} pathParts - Nested object path. + * @returns {*} Nested value. + */ +function valueAtPath(obj, pathParts) { + return pathParts.reduce( + (current, key) => + current && typeof current === 'object' ? current[key] : undefined, + obj, + ); +} + +/** + * Determine whether a package manifest depends on Emulsify Core. + * + * @param {object} packageJson - Parsed package.json. + * @returns {boolean} TRUE when package.json is Core or consumes Core. + */ +function packageUsesEmulsifyCore(packageJson = {}) { + if (packageJson.name === '@emulsify/core') { + return true; + } + + return [ + 'dependencies', + 'devDependencies', + 'peerDependencies', + 'optionalDependencies', + ].some((section) => + Object.prototype.hasOwnProperty.call( + packageJson[section] || {}, + '@emulsify/core', + ), + ); +} + +/** + * Determine whether a recommended override is already present. + * + * @param {object} overrides - package.json overrides object. + * @param {{paths: string[][]}} recommendation - Override recommendation. + * @returns {boolean} TRUE when any equivalent override path exists. + */ +function hasRecommendedOverride(overrides = {}, recommendation) { + return recommendation.paths.some( + (pathParts) => valueAtPath(overrides, pathParts) !== undefined, + ); +} + +/** + * Normalize the project config, retaining any resolution failure. + * + * @param {string} projectDir - Absolute project root. + * @returns {{env: object, configExists: boolean, error?: Error}} + */ +function resolveAuditEnvironment(projectDir) { + const configExists = safeExists(resolve(projectDir, 'project.emulsify.json')); + + try { + return { + env: resolveProjectConfig(projectDir, process.env), + configExists, + }; + } catch (error) { + return { + env: { + projectDir, + platform: 'generic', + namespaceRoots: {}, + projectStructure: {}, + }, + configExists, + error, + }; + } +} + +/** + * Audit basic project configuration and structure root health. + * + * @param {object} context - Audit context. + * @returns {object[]} Findings. + */ +function auditProjectConfig(context) { + const { configExists, env, error, projectDir } = context; + const findings = []; + + if (!configExists) { + findings.push( + makeFinding({ + id: 'missing-project-config', + severity: 'error', + message: + 'project.emulsify.json is missing, so platform and structure defaults may not match the project.', + docs: 'https://github.com/emulsify-ds/emulsify-core/blob/4.x/docs/project-structure.md', + }), + ); + } + + if (error) { + findings.push( + makeFinding({ + id: 'project-config-resolution-failed', + severity: 'error', + message: `Unable to resolve project.emulsify.json: ${error.message || error}`, + }), + ); + } + + for (const implementation of env.structureImplementations || []) { + if (!safeIsDirectory(implementation.directory)) { + findings.push( + makeFinding({ + id: 'missing-structure-implementation', + severity: 'error', + filePath: resolve(projectDir, 'project.emulsify.json'), + message: `Configured structureImplementation "${implementation.name}" does not exist: ${displayPath( + projectDir, + implementation.directory, + )}`, + docs: 'https://github.com/emulsify-ds/emulsify-core/blob/4.x/docs/project-structure.md', + }), + ); + } + } + + return findings; +} + +/** + * Audit package-level dependency override policy for installed projects. + * + * npm only applies `overrides` from the root package being installed. When + * Emulsify Core is installed into a generated theme, Core's own overrides do + * not protect that theme's transitive dependency graph. + * + * @param {object} context - Audit context. + * @returns {object[]} Findings. + */ +function auditPackageOverrides(context) { + const { projectDir } = context; + const packagePath = resolve(projectDir, 'package.json'); + + if (!safeExists(packagePath)) { + return []; + } + + const { data: packageJson, error } = safeReadJson(packagePath); + if (error) { + return [ + makeFinding({ + id: 'package-json-unreadable', + severity: 'warn', + filePath: packagePath, + message: `Unable to parse package.json: ${error.message || error}`, + }), + ]; + } + + if (!packageUsesEmulsifyCore(packageJson)) { + return []; + } + + const overrides = packageJson.overrides || {}; + const missing = RECOMMENDED_PACKAGE_OVERRIDES.filter( + (recommendation) => !hasRecommendedOverride(overrides, recommendation), + ); + + if (!missing.length) { + return []; + } + + return [ + makeFinding({ + id: 'recommended-package-overrides-missing', + severity: 'warn', + filePath: packagePath, + message: + 'package.json is missing recommended root npm overrides for Emulsify Core transitive install warnings.', + details: missing.map( + (recommendation) => + `Add overrides.${recommendation.label}: ${recommendation.value}.`, + ), + docs: 'https://github.com/emulsify-ds/emulsify-core/blob/4.x/docs/migration-4x.md#install-warning-controls', + }), + ]; +} + +/** + * Audit story files that will not be discovered by Storybook. + * + * @param {object} context - Audit context. + * @returns {object[]} Findings. + */ +function auditStoryDiscovery(context) { + const { projectDir, storyFiles } = context; + const discovered = new Set(collectStoryFiles(projectDir)); + const findings = []; + + for (const storyFile of storyFiles) { + if (discovered.has(storyFile)) continue; + + findings.push( + makeFinding({ + id: 'story-outside-discovered-roots', + severity: 'error', + filePath: storyFile, + message: + 'Story file is outside the normalized Storybook roots and will not be discovered.', + docs: 'https://github.com/emulsify-ds/emulsify-core/blob/4.x/docs/project-structure.md', + }), + ); + } + + return findings; +} + +/** + * Add legacy Twig story migration findings. + * + * @param {object} context - Audit context. + * @returns {object[]} Findings. + */ +function auditLegacyTwigStories(context) { + const { storyFiles } = context; + const findings = storyFiles + .map((filePath) => analyzeStorySource(safeReadFile(filePath), filePath)) + .filter((result) => result.shouldUpgrade); + + return findings.map((finding) => + makeFinding({ + id: 'legacy-twig-story', + severity: 'warn', + filePath: finding.filePath, + line: finding.directTemplateReturns[0]?.line, + message: + 'Twig story appears to return an HTML string directly. This remains compatible, but renderTwig() is preferred for active migrations.', + details: finding.reasons, + docs: 'https://github.com/emulsify-ds/emulsify-core/blob/4.x/docs/storybook.md#legacy-twig-story-compatibility', + }), + ); +} + +/** + * Extract string arguments passed to include() or source(). + * + * @param {string} source - Twig source. + * @returns {{type: string, value: string, line: number}[]} References. + */ +export function findTwigIncludeSourceReferences(source) { + const references = []; + const callPattern = /\b(include|source)\s*\(([\s\S]*?)\)/g; + + for (const callMatch of source.matchAll(callPattern)) { + const type = callMatch[1]; + const args = firstArgumentText(callMatch[2]); + const argsOffset = (callMatch.index || 0) + callMatch[0].indexOf(args); + const stringPattern = /['"]([^'"]+)['"]/g; + + for (const stringMatch of args.matchAll(stringPattern)) { + references.push({ + type, + value: stringMatch[1], + line: lineNumberAt(source, argsOffset + (stringMatch.index || 0)), + }); + } + } + + return references; +} + +/** + * Extract the first function argument, including array syntax. + * + * Twig include()/source() only use the first argument as the template/source + * reference. Later object values may also be strings, but they are context + * values and should not be treated as template references. + * + * @param {string} args - Function argument source. + * @returns {string} First argument source. + */ +function firstArgumentText(args) { + let quote = ''; + let depth = 0; + + for (let index = 0; index < args.length; index += 1) { + const char = args[index]; + const prev = args[index - 1]; + + if (quote) { + if (char === quote && prev !== '\\') { + quote = ''; + } + continue; + } + + if (char === '"' || char.charCodeAt(0) === 39) { + quote = char; + continue; + } + if (char === '[' || char === '{' || char === '(') { + depth += 1; + continue; + } + if (char === ']' || char === '}' || char === ')') { + depth = Math.max(0, depth - 1); + continue; + } + if (char === ',' && depth === 0) { + return args.slice(0, index); + } + } + + return args; +} + +/** + * Extract Twig namespace references such as @components/card/card.twig. + * + * @param {string} source - Twig source. + * @returns {{namespace: string, value: string, line: number}[]} Namespace refs. + */ +export function findTwigNamespaceReferences(source) { + const references = []; + const pattern = /@([A-Za-z][\w-]*)\/[A-Za-z0-9_./-]+/g; + + for (const match of source.matchAll(pattern)) { + references.push({ + namespace: match[1], + value: match[0], + line: lineNumberAt(source, match.index || 0), + }); + } + + return references; +} + +/** + * Build candidate paths for a relative Twig reference. + * + * @param {string} filePath - Referencing file. + * @param {string} reference - Twig reference. + * @returns {string[]} Absolute candidate paths. + */ +function relativeTwigCandidates(filePath, reference) { + const base = resolve(dirname(filePath), reference); + if (/\.[A-Za-z0-9]+$/.test(reference)) { + return [base]; + } + + return [`${base}.twig`, `${base}.html.twig`]; +} + +/** + * Convert resolver candidate keys into absolute filesystem paths. + * + * @param {string[]} keys - Root-relative Vite keys. + * @param {object} env - Normalized environment. + * @returns {string[]} Absolute candidate paths. + */ +function candidateKeysToFiles(keys, env) { + const projectDir = env.projectDir || process.cwd(); + + return keys.map((key) => + key.startsWith('/') ? resolve(projectDir, key.slice(1)) : resolve(key), + ); +} + +/** + * Determine whether a Twig include/source reference resolves. + * + * @param {string} reference - Twig reference. + * @param {string} filePath - Referencing file path. + * @param {object} env - Normalized environment. + * @returns {boolean} TRUE when a candidate exists. + */ +export function resolvesTwigReference(reference, filePath, env) { + if (!reference || /^https?:\/\//i.test(reference)) return true; + + if (reference.startsWith('@assets/')) { + const relAsset = reference.replace(/^@assets\//, ''); + return safeExists(resolve(env.projectDir, 'assets', relAsset)); + } + + const candidates = + reference.startsWith('./') || reference.startsWith('../') + ? relativeTwigCandidates(filePath, reference) + : candidateKeysToFiles(candidateKeysForReference(reference, env), env); + + return candidates.some(safeExists); +} + +/** + * Audit Twig namespace and include/source resolution. + * + * @param {object} context - Audit context. + * @returns {object[]} Findings. + */ +function auditTwigReferences(context) { + const { env, projectDir, twigFiles } = context; + const namespaceRoots = env.namespaceRoots || {}; + const knownNamespaces = new Set([...Object.keys(namespaceRoots), 'assets']); + const findings = []; + const seen = new Set(); + + for (const twigFile of twigFiles) { + const source = safeReadFile(twigFile); + + for (const ref of findTwigNamespaceReferences(source)) { + if (knownNamespaces.has(ref.namespace)) continue; + + const key = `${twigFile}:${ref.line}:unknown:${ref.namespace}`; + if (seen.has(key)) continue; + seen.add(key); + + findings.push( + makeFinding({ + id: 'unknown-twig-namespace', + severity: 'warn', + filePath: twigFile, + line: ref.line, + message: `Twig namespace "@${ref.namespace}" is not configured in the normalized project structure.`, + docs: 'https://github.com/emulsify-ds/emulsify-core/blob/4.x/docs/project-structure.md#twig-namespaces', + }), + ); + } + + for (const ref of findTwigIncludeSourceReferences(source)) { + if (!resolvesTwigReference(ref.value, twigFile, env)) { + findings.push( + makeFinding({ + id: 'unresolved-twig-reference', + severity: 'warn', + filePath: twigFile, + line: ref.line, + message: `${ref.type}() reference "${ref.value}" could not be resolved from the normalized Twig roots.`, + docs: 'https://github.com/emulsify-ds/emulsify-core/blob/4.x/docs/storybook.md#include', + }), + ); + } + } + } + + return findings.map((finding) => ({ + ...finding, + filePath: finding.filePath || resolve(projectDir, 'project.emulsify.json'), + })); +} + +/** + * Extract simple same-file Sass string variables. + * + * @param {string} source - Stylesheet source. + * @returns {Map} Variable value map. + */ +function findSassStringVariables(source) { + const variables = new Map(); + const pattern = /^\s*\$([\w-]+)\s*:\s*(['"])(.*?)\2\s*;?/gm; + + for (const match of source.matchAll(pattern)) { + variables.set(match[1], match[3]); + } + + return variables; +} + +/** + * Resolve same-file Sass variable interpolation in a URL value. + * + * This intentionally handles only simple string variables. It is enough to make + * common asset roots such as `#{$font-url}/Avenir.woff2` auditable without + * pretending to be a Sass compiler. + * + * @param {string} value - Raw URL value. + * @param {Map} variables - Sass variable map. + * @returns {string} URL value with known interpolations expanded. + */ +function resolveSassUrlValue(value, variables) { + return value.replace(/#\{\$([\w-]+)\}/g, (match, name) => + variables.has(name) ? variables.get(name) : match, + ); +} + +/** + * Mask style comments while preserving line and character positions. + * + * @param {string} source - Stylesheet source. + * @returns {string} Source with comments replaced by whitespace. + */ +function maskStyleComments(source) { + const blank = (match) => match.replace(/[^\n]/g, ' '); + + return source + .replace(/\/\*[\s\S]*?\*\//g, blank) + .replace(/^[\t ]*\/\/.*$/gm, blank); +} + +/** + * Extract URL references from CSS or Sass source. + * + * @param {string} source - Stylesheet source. + * @returns {{value: string, raw: string, line: number}[]} URL references. + */ +export function findCssUrlReferences(source) { + const scanSource = maskStyleComments(source); + const variables = findSassStringVariables(scanSource); + const references = []; + const pattern = /url\(\s*(?:(['"])(.*?)\1|([^'")][^)]*?))\s*\)/g; + + for (const match of scanSource.matchAll(pattern)) { + const raw = (match[2] ?? match[3] ?? '').trim(); + const value = resolveSassUrlValue(raw, variables).trim(); + + references.push({ + value, + raw, + line: lineNumberAt(source, match.index || 0), + }); + } + + return references; +} + +/** + * Determine whether a CSS URL should be skipped by filesystem checks. + * + * @param {string} value - URL value. + * @returns {boolean} TRUE when the URL is not a local relative asset path. + */ +function isNonFilesystemCssUrl(value) { + return ( + !value || + value.startsWith('#') || + value.startsWith('/') || + value.startsWith('//') || + value.startsWith('$') || + value.startsWith('#{') || + /^[a-z][a-z0-9+.-]*:/i.test(value) || + /^var\(/i.test(value) || + /^env\(/i.test(value) + ); +} + +/** + * Remove query string and hash suffixes from a URL path. + * + * @param {string} value - URL value. + * @returns {string} Path portion. + */ +function cssUrlPath(value) { + return value.split(/[?#]/)[0]; +} + +/** + * Resolve an emitted CSS output key to the actual CSS file path. + * + * Vite entry keys use `__style` internally to avoid JS/CSS collisions. The + * shared Vite config removes that suffix from emitted CSS file names. + * + * @param {string} key - Output key without extension. + * @returns {string} Emitted CSS file path relative to output root. + */ +function emittedCssRelativePath(key) { + return `${key.replace(/__style$/i, '')}.css`; +} + +/** + * Return possible runtime directories for a style file's emitted CSS. + * + * @param {string} filePath - Source stylesheet. + * @param {object} env - Normalized environment. + * @param {string} projectDir - Project root. + * @returns {string[]} Absolute runtime directories. + */ +function styleRuntimeDirectories(filePath, env, projectDir) { + if (!/\.(scss|sass|css)$/i.test(filePath)) return []; + if (basename(filePath).startsWith('_')) return []; + + const structure = env.projectStructure || {}; + if (!structure.output) return []; + + const ctx = { + projectDir, + srcDir: env.srcDir || resolve(projectDir, 'src'), + SDC: Boolean(env.SDC), + }; + const fileName = basename(filePath); + const isStorybookStyle = /^(cl-|sb-)/.test(fileName); + const key = isStorybookStyle + ? storybookStyleOutputPath(filePath, structure, ctx) + : compiledAssetOutputPath(filePath, 'css', structure, ctx); + + if (!key) return []; + + const relCss = emittedCssRelativePath(key); + const directories = [dirname(resolve(projectDir, 'dist', relCss))]; + + if (structure.mirrorComponentOutput && relCss.startsWith('components/')) { + directories.push(dirname(resolve(projectDir, relCss))); + } + + return Array.from(new Set(directories)); +} + +/** + * Audit local CSS/Sass asset URLs that Vite may leave to runtime resolution. + * + * @param {object} context - Audit context. + * @returns {object[]} Findings. + */ +function auditCssAssetReferences(context) { + const { env, projectDir, styleFiles } = context; + const findings = []; + const projectAssetsDir = resolve(projectDir, 'assets'); + const styleSourceRoots = env.projectStructure?.sourceRoots || []; + + for (const filePath of styleFiles) { + if ( + styleSourceRoots.length && + !isInsideAnyRoot(filePath, styleSourceRoots) + ) { + continue; + } + + const source = safeReadFile(filePath); + const runtimeDirs = styleRuntimeDirectories(filePath, env, projectDir); + + for (const ref of findCssUrlReferences(source)) { + if (isNonFilesystemCssUrl(ref.value)) continue; + + const assetPath = cssUrlPath(ref.value); + if (!assetPath) continue; + + const sourceAsset = firstExistingPath([ + resolve(dirname(filePath), assetPath), + ]); + const runtimeAsset = firstExistingPath( + runtimeDirs.map((directory) => resolve(directory, assetPath)), + ); + const resolvedAsset = sourceAsset || runtimeAsset; + + if (!resolvedAsset) { + findings.push( + makeFinding({ + id: 'unresolved-css-asset-reference', + severity: 'warn', + filePath, + line: ref.line, + message: `CSS asset URL "${ref.raw}" could not be resolved from the source file or expected emitted CSS location.`, + details: [ + 'Check for a typo, move the asset into a source-root-relative location Vite can resolve, or rewrite the URL to a stable Drupal/theme public path.', + ], + docs: 'https://github.com/emulsify-ds/emulsify-core/blob/4.x/docs/migration-4x.md#css-asset-urls', + }), + ); + continue; + } + + if ( + isSameOrInside(resolvedAsset, projectAssetsDir) && + (!sourceAsset || runtimeAsset || assetPath.startsWith('..')) + ) { + findings.push( + makeFinding({ + id: 'css-runtime-asset-reference', + severity: 'info', + filePath, + line: ref.line, + message: `CSS asset URL "${ref.raw}" resolves to project-level assets and may be left unchanged by Vite for runtime resolution.`, + details: [ + `Resolved asset: ${displayPath(projectDir, resolvedAsset)}.`, + 'This is acceptable when Drupal serves the asset at that runtime URL. To make Vite bundle or rebase it, move the asset under a source root and reference it from the authored stylesheet.', + ], + docs: 'https://github.com/emulsify-ds/emulsify-core/blob/4.x/docs/migration-4x.md#css-asset-urls', + }), + ); + } + } + } + + return findings; +} + +/** + * Audit Webpack-era files and code patterns. + * + * @param {object} context - Audit context. + * @returns {object[]} Findings. + */ +function auditWebpackPatterns(context) { + const { codeFiles, projectDir } = context; + const findings = []; + const webpackConfig = resolve(projectDir, '.storybook/webpack.config.js'); + const webpackDir = resolve(projectDir, 'config/webpack'); + + if (safeExists(webpackConfig)) { + findings.push( + makeFinding({ + id: 'webpack-config-file', + severity: 'warn', + filePath: webpackConfig, + message: + 'Webpack-specific Storybook config is present and should be migrated to Vite/Storybook overrides.', + docs: 'https://github.com/emulsify-ds/emulsify-core/blob/4.x/docs/migration-4x.md#vite-customization', + }), + ); + } + + if (safeIsDirectory(webpackDir)) { + findings.push( + makeFinding({ + id: 'webpack-config-directory', + severity: 'warn', + filePath: webpackDir, + message: + 'config/webpack exists. Webpack-specific customization should move to Vite plugins or extendConfig().', + docs: 'https://github.com/emulsify-ds/emulsify-core/blob/4.x/docs/extension-points.md#vite-plugins-and-config-patches', + }), + ); + } + + const patterns = [ + { + regex: /\brequire\.context\s*\(/, + message: 'require.context() is Webpack-specific and should be migrated.', + }, + { + regex: + /\b(raw-loader|twig-loader|style-loader|file-loader|sass-loader)\b/, + message: 'Webpack loader references should be migrated to Vite plugins.', + }, + { + regex: /from\s+['"][^'"]+![^'"]+['"]|import\s+['"][^'"]+![^'"]+['"]/, + message: 'Inline Webpack loader import syntax should be removed.', + }, + ]; + + for (const filePath of codeFiles) { + const source = safeReadFile(filePath); + + for (const pattern of patterns) { + const match = pattern.regex.exec(source); + if (!match) continue; + + findings.push( + makeFinding({ + id: 'webpack-era-pattern', + severity: 'warn', + filePath, + line: lineNumberAt(source, match.index || 0), + message: pattern.message, + docs: 'https://github.com/emulsify-ds/emulsify-core/blob/4.x/docs/migration-4x.md#vite-customization', + }), + ); + } + } + + return findings; +} + +/** + * Extract import specifiers from JavaScript source. + * + * @param {string} source - JavaScript source. + * @returns {{specifier: string, index: number}[]} Import specifiers. + */ +function findImportSpecifiers(source) { + const imports = []; + const patterns = [ + /(?:import|export)\s+(?:[^'"]+\s+from\s+)?['"]([^'"]+)['"]/g, + /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g, + /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g, + ]; + + for (const pattern of patterns) { + for (const match of source.matchAll(pattern)) { + imports.push({ + specifier: match[1], + index: match.index || 0, + }); + } + } + + return imports; +} + +/** + * Audit direct imports of Emulsify Core internals. + * + * @param {object} context - Audit context. + * @returns {object[]} Findings. + */ +function auditCoreImports(context) { + const { codeFiles } = context; + const findings = []; + + for (const filePath of codeFiles) { + const source = safeReadFile(filePath); + + for (const item of findImportSpecifiers(source)) { + const { specifier } = item; + if (!specifier.startsWith('@emulsify/core/')) continue; + if (PUBLIC_CORE_IMPORTS.has(specifier)) continue; + + findings.push( + makeFinding({ + id: 'internal-core-import', + severity: 'warn', + filePath, + line: lineNumberAt(source, item.index), + message: `Import "${specifier}" uses an internal Emulsify Core path. Prefer a public package export.`, + docs: 'https://github.com/emulsify-ds/emulsify-core/blob/4.x/README.md#public-imports', + }), + ); + } + } + + return findings; +} + +/** + * Audit Drupal assumptions in non-Drupal projects. + * + * @param {object} context - Audit context. + * @returns {object[]} Findings. + */ +function auditDrupalAssumptions(context) { + const { codeFiles, env } = context; + if (env.platform === 'drupal') return []; + + const findings = []; + const patterns = [ + /\bDrupal\.attachBehaviors\b/, + /\bwindow\.Drupal\b/, + /\bglobalThis\.Drupal\b/, + /['"][^'"]*_drupal\.js['"]/, + /['"]twig-drupal-filters['"]/, + ]; + + for (const filePath of codeFiles) { + const source = safeReadFile(filePath); + const match = patterns.map((pattern) => pattern.exec(source)).find(Boolean); + + if (!match) continue; + + findings.push( + makeFinding({ + id: 'drupal-assumption-non-drupal', + severity: 'warn', + filePath, + line: lineNumberAt(source, match.index || 0), + message: + 'Drupal-specific Storybook/runtime code was found, but the active platform is not drupal.', + docs: 'https://github.com/emulsify-ds/emulsify-core/blob/4.x/docs/platform-adapters.md', + }), + ); + } + + return findings; +} + +/** + * Audit files that look like component Twig files outside source roots. + * + * @param {object} context - Audit context. + * @returns {object[]} Findings. + */ +function auditFilesOutsideRoots(context) { + const { env, projectDir, twigFiles } = context; + const roots = [ + ...(env.projectStructure?.twigRoots || []), + ...(env.projectStructure?.sourceRoots || []), + ]; + + if (!roots.length) return []; + + return twigFiles + .filter((filePath) => !isInsideAnyRoot(filePath, roots)) + .map((filePath) => + makeFinding({ + id: 'twig-file-outside-source-roots', + severity: 'info', + filePath, + message: + 'Twig file is outside normalized source roots and will not be available to Storybook include()/source() unless another integration loads it.', + docs: 'https://github.com/emulsify-ds/emulsify-core/blob/4.x/docs/project-structure.md', + }), + ) + .filter((finding) => !isNonComponentTwigFile(projectDir, finding.filePath)); +} + +/** + * Determine whether a Twig file is intentionally outside component roots. + * + * @param {string} projectDir - Absolute project root. + * @param {string} filePath - Absolute Twig file path. + * @returns {boolean} TRUE when the file should not be treated as component source. + */ +function isNonComponentTwigFile(projectDir, filePath) { + const relPath = displayPath(projectDir, filePath); + + return ( + relPath.startsWith('docs/') || + relPath.startsWith('templates/') || + relPath.includes('/templates/') + ); +} + +/** + * Recursively measure a directory size. + * + * @param {string} directory - Directory path. + * @returns {number} Size in bytes. + */ +function directorySize(directory) { + let total = 0; + + try { + for (const entry of readdirSync(directory)) { + const entryPath = resolve(directory, entry); + const stats = statSync(entryPath); + total += stats.isDirectory() ? directorySize(entryPath) : stats.size; + } + } catch { + return total; + } + + return total; +} + +/** + * Audit Twig volume under Storybook roots. + * + * @param {object} context - Audit context. + * @returns {object[]} Findings. + */ +function auditTwigVolume(context) { + const { env, twigThreshold } = context; + const roots = Array.from(new Set(env.projectStructure?.twigRoots || [])); + const twigFiles = new Set(); + + for (const root of roots) { + if (!safeIsDirectory(root)) continue; + for (const filePath of globSync(TWIG_GLOB, { + cwd: root, + absolute: true, + nodir: true, + ignore: DEFAULT_IGNORES, + })) { + twigFiles.add(resolve(filePath)); + } + } + + if (twigFiles.size <= twigThreshold) return []; + + const totalBytes = roots.reduce( + (total, root) => total + directorySize(root), + 0, + ); + + return [ + makeFinding({ + id: 'large-twig-storybook-roots', + severity: 'info', + message: `${twigFiles.size} Twig files are under Storybook Twig roots. Eager Twig imports are reliable but can increase Storybook startup/build cost for large libraries.`, + details: [ + `Approximate Twig root size: ${Math.round(totalBytes / 1024)} KB.`, + ], + docs: 'https://github.com/emulsify-ds/emulsify-core/blob/4.x/docs/performance.md#storybook-twig-imports', + }), + ]; +} + +/** + * Run the combined Emulsify audit. + * + * @param {{projectDir?: string, twigThreshold?: number}} [options={}] - Options. + * @returns {{projectDir: string, summary: object, findings: object[]}} Audit result. + */ +export function auditProject(options = {}) { + const projectDir = resolve(options.projectDir || process.cwd()); + const envResult = resolveAuditEnvironment(projectDir); + const structure = envResult.env.projectStructure || {}; + const sourceRoots = normalizeAuditRoots( + projectDir, + structure.sourceRoots || [], + ); + const storyRoots = normalizeAuditRoots( + projectDir, + structure.storyRoots || sourceRoots, + ); + const twigRoots = normalizeAuditRoots( + projectDir, + structure.twigRoots || sourceRoots, + ); + const storyFiles = collectRootedProjectFiles( + projectDir, + STORY_GLOB, + storyRoots, + ); + const codeFiles = collectRootedProjectFiles( + projectDir, + CODE_GLOB, + sourceRoots, + ); + const twigFiles = collectRootedProjectFiles(projectDir, TWIG_GLOB, twigRoots); + const styleFiles = collectRootedProjectFiles( + projectDir, + STYLE_GLOB, + sourceRoots, + ); + const context = { + ...envResult, + projectDir, + sourceRoots, + storyRoots, + twigRoots, + storyFiles, + codeFiles, + twigFiles, + styleFiles, + twigThreshold: Number.isFinite(options.twigThreshold) + ? options.twigThreshold + : DEFAULT_TWIG_THRESHOLD, + }; + const findings = [ + ...auditProjectConfig(context), + ...auditPackageOverrides(context), + ...auditStoryDiscovery(context), + ...auditLegacyTwigStories(context), + ...auditTwigReferences(context), + ...auditCssAssetReferences(context), + ...auditWebpackPatterns(context), + ...auditCoreImports(context), + ...auditDrupalAssumptions(context), + ...auditFilesOutsideRoots(context), + ...auditTwigVolume(context), + ]; + const summary = findings.reduce( + (totals, finding) => ({ + ...totals, + [finding.severity]: (totals[finding.severity] || 0) + 1, + }), + { + error: 0, + warn: 0, + info: 0, + }, + ); + + return { + projectDir, + summary, + files: { + stories: storyFiles.length, + twig: twigFiles.length, + code: codeFiles.length, + styles: styleFiles.length, + }, + findings, + }; +} + +/** + * Format one finding for terminal output. + * + * @param {object} finding - Finding to format. + * @param {string} projectDir - Project root. + * @returns {string[]} Output lines. + */ +function formatFinding(finding, projectDir) { + const location = finding.filePath + ? `${displayPath(projectDir, finding.filePath)}${ + finding.line ? `:${finding.line}` : '' + }` + : 'project'; + const lines = [ + `[${finding.severity}] ${finding.id}`, + ` ${location}`, + ` ${finding.message}`, + ]; + + for (const detail of finding.details || []) { + lines.push(` ${detail}`); + } + if (finding.docs) { + lines.push(` Docs: ${finding.docs}`); + } + + return lines; +} + +/** + * Format the combined audit report. + * + * @param {{projectDir: string, summary: object, files: object, findings: object[]}} result + * Audit result. + * @returns {string} Human-readable report. + */ +export function formatAuditReport(result) { + const lines = [ + 'Emulsify project audit', + `Project: ${result.projectDir}`, + `Scanned ${result.files.stories} story file(s), ${result.files.twig} Twig file(s), ${result.files.code} code file(s), and ${result.files.styles} style file(s).`, + `Findings: ${result.summary.error} error(s), ${result.summary.warn} warning(s), ${result.summary.info} info item(s).`, + ]; + + if (!result.findings.length) { + lines.push('No audit findings found.'); + return lines.join('\n'); + } + + for (const finding of result.findings) { + lines.push('', ...formatFinding(finding, result.projectDir)); + } + + return lines.join('\n'); +} + +/** + * CLI usage text. + * + * @returns {string} Usage text. + */ +function usage() { + return [ + 'Usage: emulsify-audit [--root ] [--json] [--fail-on-found] [--twig-threshold ]', + '', + 'Options:', + ' --root Project root to scan. Defaults to the current directory.', + ' --json Print machine-readable JSON.', + ' --fail-on-found Exit with code 1 when any finding is reported.', + ` --twig-threshold Warn when Storybook roots contain more than this many Twig files. Default: ${DEFAULT_TWIG_THRESHOLD}.`, + ' --help Print this help text.', + ].join('\n'); +} + +/** + * Parse command-line arguments. + * + * @param {string[]} argv - CLI arguments. + * @returns {object} Parsed options. + */ +function parseArgs(argv) { + const options = { + projectDir: process.cwd(), + failOnFound: false, + json: false, + help: false, + twigThreshold: DEFAULT_TWIG_THRESHOLD, + }; + + for (let index = 0; index < argv.length; index += 1) { + const arg = argv[index]; + + if (arg === '--help' || arg === '-h') { + options.help = true; + continue; + } + if (arg === '--fail-on-found') { + options.failOnFound = true; + continue; + } + if (arg === '--json') { + options.json = true; + continue; + } + if (arg === '--root') { + const value = argv[index + 1]; + if (!value || value.startsWith('--')) { + throw new Error('--root requires a project directory.'); + } + options.projectDir = value; + index += 1; + continue; + } + if (arg.startsWith('--root=')) { + options.projectDir = arg.slice('--root='.length); + continue; + } + if (arg === '--twig-threshold') { + const value = Number(argv[index + 1]); + if (!Number.isFinite(value)) { + throw new Error('--twig-threshold requires a number.'); + } + options.twigThreshold = value; + index += 1; + continue; + } + if (arg.startsWith('--twig-threshold=')) { + const value = Number(arg.slice('--twig-threshold='.length)); + if (!Number.isFinite(value)) { + throw new Error('--twig-threshold requires a number.'); + } + options.twigThreshold = value; + continue; + } + + throw new Error(`Unknown option: ${arg}`); + } + + return options; +} + +/** + * Run the CLI. + * + * @param {string[]} argv - CLI arguments. + * @returns {number} Exit code. + */ +export function runCli(argv = process.argv.slice(2)) { + const options = parseArgs(argv); + + if (options.help) { + console.log(usage()); + return 0; + } + + const result = auditProject(options); + + if (options.json) { + console.log(JSON.stringify(result, null, 2)); + } else { + console.log(formatAuditReport(result)); + } + + return options.failOnFound && result.findings.length ? 1 : 0; +} + +if (process.argv[1]?.split(/[\\/]/).pop() === 'audit.js') { + try { + process.exitCode = runCli(); + } catch (error) { + console.error(error.message || error); + console.error(''); + console.error(usage()); + process.exitCode = 1; + } +} diff --git a/scripts/audit.test.js b/scripts/audit.test.js new file mode 100644 index 0000000..30ec256 --- /dev/null +++ b/scripts/audit.test.js @@ -0,0 +1,368 @@ +/** + * @file Tests for the combined Emulsify audit. + */ + +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { dirname, join } from 'node:path'; +import { + auditProject, + findCssUrlReferences, + findTwigIncludeSourceReferences, + formatAuditReport, +} from './audit.js'; + +function writeFile(projectDir, relPath, contents = '') { + const filePath = join(projectDir, relPath); + mkdirSync(dirname(filePath), { recursive: true }); + writeFileSync(filePath, contents); + return filePath; +} + +describe('audit', () => { + let projectDir; + + beforeEach(() => { + projectDir = mkdtempSync(join(tmpdir(), 'emulsify-audit-')); + }); + + afterEach(() => { + rmSync(projectDir, { recursive: true, force: true }); + }); + + it('reports combined readiness findings', () => { + writeFile( + projectDir, + 'project.emulsify.json', + JSON.stringify({ + project: { + platform: 'generic', + name: 'Audit fixture', + machineName: 'audit_fixture', + }, + }), + ); + writeFile( + projectDir, + 'src/components/card/card.twig', + ` + {{ include('@components/card/_content.twig', { label: 'OK' }) }} + {{ include('@missing/card.twig') }} + `, + ); + writeFile( + projectDir, + 'src/components/card/_content.twig', + '

{{ label }}

', + ); + writeFile( + projectDir, + 'src/components/card/card.stories.js', + ` + import cardTwig from './card.twig'; + import { renderTwig } from '@emulsify/core/src/storybook/render-twig.js'; + require.context('./', true, /stories/); + window.Drupal.attachBehaviors(); + export const Card = (args) => cardTwig(args); + `, + ); + writeFile( + projectDir, + 'stories/outside.stories.js', + 'export const Outside = {};', + ); + + const result = auditProject({ projectDir, twigThreshold: 1 }); + const ids = result.findings.map((finding) => finding.id); + const report = formatAuditReport(result); + + expect(ids).toEqual( + expect.arrayContaining([ + 'legacy-twig-story', + 'unknown-twig-namespace', + 'unresolved-twig-reference', + 'webpack-era-pattern', + 'internal-core-import', + 'drupal-assumption-non-drupal', + 'large-twig-storybook-roots', + ]), + ); + expect(report).toContain('Emulsify project audit'); + expect(report).not.toContain('stories/outside.stories.js'); + }); + + it('reports missing project config and missing configured roots', () => { + writeFile( + projectDir, + 'project.emulsify.json', + JSON.stringify({ + project: { + platform: 'generic', + }, + variant: { + structureImplementations: [ + { + name: 'components', + directory: './missing-components', + }, + ], + }, + }), + ); + + const result = auditProject({ projectDir }); + + expect(result.findings.map((finding) => finding.id)).toContain( + 'missing-structure-implementation', + ); + }); + + it('reports missing recommended package overrides for Core consumers', () => { + writeFile( + projectDir, + 'project.emulsify.json', + JSON.stringify({ + project: { + platform: 'generic', + }, + }), + ); + writeFile( + projectDir, + 'package.json', + JSON.stringify({ + name: 'consumer-theme', + dependencies: { + '@emulsify/core': '^4.0.0', + }, + }), + ); + + const result = auditProject({ projectDir }); + const finding = result.findings.find( + (item) => item.id === 'recommended-package-overrides-missing', + ); + + expect(finding.details).toEqual([ + 'Add overrides.glob: ^13.0.6.', + 'Add overrides.locutus: ^3.0.36.', + 'Add overrides.minimatch@3.0.x: ^3.1.5.', + ]); + }); + + it('accepts recommended package overrides for Core consumers', () => { + writeFile( + projectDir, + 'project.emulsify.json', + JSON.stringify({ + project: { + platform: 'generic', + }, + }), + ); + writeFile( + projectDir, + 'package.json', + JSON.stringify({ + name: 'consumer-theme', + dependencies: { + '@emulsify/core': '^4.0.0', + }, + overrides: { + glob: '^13.0.6', + locutus: '^3.0.36', + 'minimatch@3.0.x': '^3.1.5', + }, + }), + ); + + const result = auditProject({ projectDir }); + + expect(result.findings.map((finding) => finding.id)).not.toContain( + 'recommended-package-overrides-missing', + ); + }); + + it('only treats first include/source argument strings as template references', () => { + const quote = String.fromCharCode(39); + + expect( + findTwigIncludeSourceReferences( + `{{ include(${quote}@components/card/card.twig${quote}, { label: ${quote}Not a template${quote} }) }}`, + ), + ).toEqual([ + { + type: 'include', + value: '@components/card/card.twig', + line: 1, + }, + ]); + }); + + it('expands simple Sass variables in CSS URL references', () => { + const quote = String.fromCharCode(39); + + expect( + findCssUrlReferences( + [ + '$font-url: ' + quote + '../../../assets/fonts' + quote + ';', + '@font-face { src: url(' + + quote + + '#{$font-url}/Avenir.woff2' + + quote + + '); }', + ].join('\n'), + ), + ).toEqual([ + { + value: '../../../assets/fonts/Avenir.woff2', + raw: '#{$font-url}/Avenir.woff2', + line: 2, + }, + ]); + }); + + it('ignores CSS URL references in comments', () => { + expect( + findCssUrlReferences( + [ + '// mask-image: url("../icons/commented.svg");', + '/* background: url("../icons/blocked.svg"); */', + '.real { background: url("../icons/real.svg"); }', + ].join('\n'), + ), + ).toEqual([ + { + value: '../icons/real.svg', + raw: '../icons/real.svg', + line: 3, + }, + ]); + }); + + it('reports CSS asset references that rely on runtime project assets', () => { + const quote = String.fromCharCode(39); + + writeFile( + projectDir, + 'project.emulsify.json', + JSON.stringify({ + project: { + platform: 'drupal', + singleDirectoryComponents: true, + }, + }), + ); + writeFile(projectDir, 'assets/fonts/Avenir.woff2', 'font'); + writeFile(projectDir, 'assets/icons/search.svg', ''); + writeFile( + projectDir, + 'src/foundation/typography/_fonts.scss', + [ + '$font-url: ' + quote + '../../../assets/fonts' + quote + ';', + '@font-face { src: url(' + + quote + + '#{$font-url}/Avenir.woff2' + + quote + + '); }', + ].join('\n'), + ); + writeFile( + projectDir, + 'src/components/search/search.scss', + '.search { mask-image: url("../../assets/icons/search.svg"); }', + ); + + const result = auditProject({ projectDir }); + const findings = result.findings.filter( + (finding) => finding.id === 'css-runtime-asset-reference', + ); + + expect(findings).toHaveLength(2); + expect(findings.map((finding) => finding.filePath)).toEqual( + expect.arrayContaining([ + expect.stringContaining('src/foundation/typography/_fonts.scss'), + expect.stringContaining('src/components/search/search.scss'), + ]), + ); + }); + + it('reports unresolved CSS asset references', () => { + writeFile( + projectDir, + 'project.emulsify.json', + JSON.stringify({ + project: { + platform: 'generic', + }, + }), + ); + writeFile( + projectDir, + 'src/components/card/card.scss', + '.card { background-image: url("./missing.svg"); }', + ); + + const result = auditProject({ projectDir }); + + expect(result.findings.map((finding) => finding.id)).toContain( + 'unresolved-css-asset-reference', + ); + }); + + it('does not report conventional template override files as component source roots', () => { + writeFile( + projectDir, + 'project.emulsify.json', + JSON.stringify({ + project: { + platform: 'drupal', + }, + }), + ); + writeFile(projectDir, 'templates/layout/page.html.twig', '
'); + + const result = auditProject({ projectDir }); + + expect(result.findings.map((finding) => finding.id)).not.toContain( + 'twig-file-outside-source-roots', + ); + }); + + it('scans canonical source roots instead of generated components or Drupal templates', () => { + writeFile( + projectDir, + 'project.emulsify.json', + JSON.stringify({ + project: { + platform: 'drupal', + singleDirectoryComponents: true, + }, + }), + ); + writeFile( + projectDir, + 'src/components/card/card.twig', + '{{ include("@missing/source.twig") }}', + ); + writeFile( + projectDir, + 'components/card/card.twig', + '{{ include("@missing/generated.twig") }}', + ); + writeFile( + projectDir, + 'templates/layout/page.html.twig', + '{{ include("@missing/template.twig") }}', + ); + + const result = auditProject({ projectDir }); + const unresolved = result.findings.filter( + (finding) => finding.id === 'unresolved-twig-reference', + ); + + expect(unresolved).toHaveLength(1); + expect(unresolved[0].message).toContain('@missing/source.twig'); + expect(result.files.twig).toBe(1); + }); +}); diff --git a/scripts/bump-version-from-commits.js b/scripts/bump-version-from-commits.js new file mode 100644 index 0000000..d33770b --- /dev/null +++ b/scripts/bump-version-from-commits.js @@ -0,0 +1,231 @@ +#!/usr/bin/env node + +/** + * @file Update package versions from semantic commits in a git range. + */ + +import { execFileSync } from 'node:child_process'; +import { readFileSync, writeFileSync } from 'node:fs'; +import { resolve } from 'node:path'; + +const ZERO_SHA = /^0+$/; +const RELEASE_TYPES = new Set(['major', 'minor', 'patch']); +const semanticReleaseConfig = { + preset: 'angular', + parserOpts: { + noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES', 'BREAKING'], + }, +}; + +const logger = { + log: () => {}, +}; + +/** + * Determine whether a git SHA is the all-zero value used for new refs. + * + * @param {string} value - Git SHA value. + * @returns {boolean} TRUE when the value is empty or all zeroes. + */ +export function isZeroSha(value) { + return !value || ZERO_SHA.test(value); +} + +/** + * Build the git revision range used by a develop push event. + * + * @param {string} from - Previous SHA from the push event. + * @param {string} to - Current SHA from the push event. + * @returns {string} Git revision or revision range. + */ +export function buildCommitRange(from, to = 'HEAD') { + return isZeroSha(from) ? to : `${from}..${to}`; +} + +/** + * Parse git log output into semantic-release commit objects. + * + * @param {string} output - Git log output using record and field separators. + * @returns {{hash: string, message: string}[]} Parsed commits. + */ +export function parseGitLog(output) { + return output + .split('\x1e') + .map((record) => record.trim()) + .filter(Boolean) + .map((record) => { + const separator = record.indexOf('\0'); + + return { + hash: record.slice(0, separator).trim(), + message: record.slice(separator + 1).trim(), + }; + }) + .filter(({ hash, message }) => hash && message); +} + +/** + * Read commits from a git revision range. + * + * @param {{cwd: string, from?: string, to?: string}} options - Git options. + * @returns {{hash: string, message: string}[]} Commit objects. + */ +export function getCommitsInRange({ cwd, from, to = 'HEAD' }) { + const range = buildCommitRange(from, to); + const output = execFileSync('git', ['log', '--format=%x1e%H%x00%B', range], { + cwd, + encoding: 'utf8', + }); + + return parseGitLog(output); +} + +/** + * Analyze commits with the same conventional rules as semantic-release. + * + * @param {{hash: string, message: string}[]} commits - Commits to analyze. + * @param {string} cwd - Repository working directory. + * @returns {Promise} Release type or null when no bump is needed. + */ +export async function analyzeReleaseType(commits, cwd) { + const { analyzeCommits } = await import('@semantic-release/commit-analyzer'); + + return analyzeCommits(semanticReleaseConfig, { + commits, + cwd, + logger, + }); +} + +/** + * Increment a semver version by a release type. + * + * @param {string} version - Current package version. + * @param {string} releaseType - semantic-release release type. + * @returns {string} Next package version. + */ +export function incrementVersion(version, releaseType) { + if (!RELEASE_TYPES.has(releaseType)) { + throw new Error(`Unsupported release type: ${releaseType}`); + } + + const match = /^(\d+)\.(\d+)\.(\d+)(?:-.+)?$/.exec(version); + if (!match) { + throw new Error(`Unsupported package version: ${version}`); + } + + let major = Number(match[1]); + let minor = Number(match[2]); + let patch = Number(match[3]); + + if (releaseType === 'major') { + major += 1; + minor = 0; + patch = 0; + } + + if (releaseType === 'minor') { + minor += 1; + patch = 0; + } + + if (releaseType === 'patch') { + patch += 1; + } + + return `${major}.${minor}.${patch}`; +} + +/** + * Update package metadata objects with a new version. + * + * @param {Object} packageJson - Parsed package.json data. + * @param {Object} packageLock - Parsed package-lock.json data. + * @param {string} nextVersion - Version to apply. + * @returns {{packageJson: Object, packageLock: Object}} Updated package data. + */ +export function updatePackageVersions(packageJson, packageLock, nextVersion) { + packageJson.version = nextVersion; + packageLock.version = nextVersion; + + if (packageLock.packages?.['']) { + packageLock.packages[''].version = nextVersion; + } + + return { + packageJson, + packageLock, + }; +} + +/** + * Read a JSON file from disk. + * + * @param {string} filePath - JSON file path. + * @returns {Object} Parsed JSON. + */ +function readJson(filePath) { + return JSON.parse(readFileSync(filePath, 'utf8')); +} + +/** + * Write formatted JSON to disk. + * + * @param {string} filePath - JSON file path. + * @param {Object} data - JSON data. + */ +function writeJson(filePath, data) { + writeFileSync(filePath, `${JSON.stringify(data, null, 2)}\n`); +} + +/** + * Update package files when semantic commits in a range require a bump. + * + * @param {{cwd: string, from?: string, to?: string}} options - Runtime options. + * @returns {Promise<{changed: boolean, releaseType: string|null, version?: string}>} + * Result metadata. + */ +export async function runVersionBump({ cwd, from, to = 'HEAD' }) { + const commits = getCommitsInRange({ cwd, from, to }); + const releaseType = await analyzeReleaseType(commits, cwd); + + if (!releaseType) { + console.log('No semantic version bump detected.'); + return { + changed: false, + releaseType: null, + }; + } + + const packageJsonPath = resolve(cwd, 'package.json'); + const packageLockPath = resolve(cwd, 'package-lock.json'); + const packageJson = readJson(packageJsonPath); + const packageLock = readJson(packageLockPath); + const currentVersion = packageJson.version; + const nextVersion = incrementVersion(currentVersion, releaseType); + + updatePackageVersions(packageJson, packageLock, nextVersion); + writeJson(packageJsonPath, packageJson); + writeJson(packageLockPath, packageLock); + + console.log( + `Updated package.json and package-lock.json from ${currentVersion} to ${nextVersion}.`, + ); + + return { + changed: true, + releaseType, + version: nextVersion, + }; +} + +if (process.argv[1]?.split(/[\\/]/).pop() === 'bump-version-from-commits.js') { + runVersionBump({ + cwd: process.cwd(), + from: process.argv[2] || process.env.GITHUB_EVENT_BEFORE, + to: process.argv[3] || process.env.GITHUB_SHA || 'HEAD', + }).catch((error) => { + console.error(error); + process.exitCode = 1; + }); +} diff --git a/scripts/bump-version-from-commits.test.js b/scripts/bump-version-from-commits.test.js new file mode 100644 index 0000000..e00b219 --- /dev/null +++ b/scripts/bump-version-from-commits.test.js @@ -0,0 +1,72 @@ +/** + * @file Tests for develop branch semantic version bumping. + */ + +import { + buildCommitRange, + incrementVersion, + isZeroSha, + parseGitLog, + updatePackageVersions, +} from './bump-version-from-commits.js'; + +describe('develop version bump helpers', () => { + it('detects zero SHAs from new branch push events', () => { + expect(isZeroSha('0000000000000000000000000000000000000000')).toBe(true); + expect(isZeroSha('abc123')).toBe(false); + }); + + it('builds a push commit range', () => { + expect(buildCommitRange('abc123', 'def456')).toBe('abc123..def456'); + expect( + buildCommitRange('0000000000000000000000000000000000000000', 'def456'), + ).toBe('def456'); + }); + + it('parses git log records with full commit messages', () => { + expect( + parseGitLog( + '\x1eabc123\0feat: add thing\n\nBody text\n\x1edef456\0fix: patch thing\n', + ), + ).toEqual([ + { + hash: 'abc123', + message: 'feat: add thing\n\nBody text', + }, + { + hash: 'def456', + message: 'fix: patch thing', + }, + ]); + }); + + it('increments semantic versions by release type', () => { + expect(incrementVersion('1.2.3', 'patch')).toBe('1.2.4'); + expect(incrementVersion('1.2.3', 'minor')).toBe('1.3.0'); + expect(incrementVersion('1.2.3', 'major')).toBe('2.0.0'); + }); + + it('updates package and lockfile versions together', () => { + const packageJson = { version: '1.2.3' }; + const packageLock = { + version: '1.2.3', + packages: { + '': { + version: '1.2.3', + }, + }, + }; + + expect(updatePackageVersions(packageJson, packageLock, '1.3.0')).toEqual({ + packageJson: { version: '1.3.0' }, + packageLock: { + version: '1.3.0', + packages: { + '': { + version: '1.3.0', + }, + }, + }, + }); + }); +}); diff --git a/scripts/check-node-version.js b/scripts/check-node-version.js new file mode 100644 index 0000000..ed4d24b --- /dev/null +++ b/scripts/check-node-version.js @@ -0,0 +1,18 @@ +#!/usr/bin/env node +/** + * @file Enforces the supported Node.js floor for project scripts. + */ + +const REQUIRED_NODE_MAJOR = 24; +const [currentNodeMajor] = process.versions.node.split('.').map(Number); + +if (currentNodeMajor < REQUIRED_NODE_MAJOR) { + // Fail before npm scripts run with an unsupported runtime. + console.error( + `Emulsify Core requires Node.js ${REQUIRED_NODE_MAJOR} or later. ` + + `Current version: ${process.versions.node}. Run nvm use or install Node.js 24+.`, + ); + process.exit(1); +} + +// Keep successful checks quiet so script output belongs to the called command. diff --git a/scripts/loadYaml.fixture.yml b/scripts/loadYaml.fixture.yml new file mode 100644 index 0000000..717a88b --- /dev/null +++ b/scripts/loadYaml.fixture.yml @@ -0,0 +1,2 @@ +# Fixture value used by scripts/loadYaml.test.js. +the: yaml spaghetti and meatballs diff --git a/scripts/loadYaml.js b/scripts/loadYaml.js index 4f2af65..f3e20d4 100644 --- a/scripts/loadYaml.js +++ b/scripts/loadYaml.js @@ -1,7 +1,10 @@ +/** + * @file YAML fixture loader used by tests and small utility scripts. + */ + import { resolve } from 'path'; import { readFileSync } from 'fs'; import { parse } from 'yaml'; -import R from 'ramda'; /** * Small utility function that loads a yaml file and parses it synchronously. @@ -12,6 +15,7 @@ import R from 'ramda'; * @returns {string} JavaScript object that results from the yaml parsing of the specified file. */ export default function loadYaml(relativePath) { + // Resolve from this script directory so tests can pass stable relative paths. const fullPath = resolve(__dirname, relativePath); return parse(readFileSync(fullPath, 'utf8')); } diff --git a/scripts/loadYaml.test.js b/scripts/loadYaml.test.js index fd144a1..f81434a 100644 --- a/scripts/loadYaml.test.js +++ b/scripts/loadYaml.test.js @@ -1,30 +1,15 @@ -import fs from 'fs'; -import yaml from 'yaml'; -import loadYaml from './loadYaml'; - -jest - .spyOn(fs, 'readFileSync') - .mockImplementation(() => 'yaml spaghetti and meatballs'); +/** + * @file Tests for the synchronous YAML loader. + */ -jest.spyOn(yaml, 'parse').mockImplementation(() => ({ - the: 'yaml spaghetti and meatballs', -})); +import loadYaml from './loadYaml'; describe('loadYaml', () => { - beforeEach(() => { - fs.readFileSync.mockClear(); - yaml.parse.mockClear(); - }); - it('can load a yaml file, parse it, and return it', () => { - expect.assertions(3); - expect(loadYaml('./big-phat-burger.yml')).toEqual({ + // The fixture is intentionally tiny so failures point to loader behavior. + expect.assertions(1); + expect(loadYaml('./loadYaml.fixture.yml')).toEqual({ the: 'yaml spaghetti and meatballs', }); - expect(fs.readFileSync).toHaveBeenCalledWith( - `${__dirname}/big-phat-burger.yml`, - 'utf8', - ); - expect(yaml.parse).toHaveBeenCalledWith('yaml spaghetti and meatballs'); }); }); diff --git a/scripts/release-fixtures.js b/scripts/release-fixtures.js new file mode 100644 index 0000000..1f89a4e --- /dev/null +++ b/scripts/release-fixtures.js @@ -0,0 +1,429 @@ +/** + * @file Release-readiness fixture builds for Emulsify Core. + */ + +import { + cpSync, + mkdirSync, + mkdtempSync, + readdirSync, + rmSync, + statSync, + symlinkSync, + writeFileSync, +} from 'node:fs'; +import { tmpdir } from 'node:os'; +import { dirname, join, resolve } from 'node:path'; +import { spawnSync } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; +import { globSync } from 'glob'; +import { safeExists } from '../config/vite/utils/fs-safe.js'; + +const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..'); +const fixturesRoot = join(repoRoot, '.github/fixtures/release'); +const viteBin = join(repoRoot, 'node_modules/vite/bin/vite.js'); +const storybookBin = join(repoRoot, 'node_modules/.bin/storybook'); +const viteConfig = join(repoRoot, 'config/vite/vite.config.js'); +const storybookConfigDir = join(repoRoot, '.storybook'); +const largeTwigComponentCount = 80; + +const releaseFixtures = [ + { + name: 'drupal-sdc-src-components', + type: 'vite', + assert: [ + 'components/card/card.js', + 'components/card/card.css', + 'components/card/card.twig', + 'components/card/card.component.yml', + 'components/card/card.asset.txt', + ], + reject: ['dist/components/card/card.js'], + }, + { + name: 'generic-src-components', + type: 'vite', + assert: [ + 'dist/components/card/js/card.js', + 'dist/components/card/css/card.css', + 'dist/components/card/card.twig', + 'dist/components/card/card.asset.txt', + 'dist/global/base/js/base.js', + 'dist/global/base/css/base.css', + 'dist/extension-marker.txt', + ], + reject: ['components/card/card.js'], + }, + { + name: 'legacy-components', + type: 'vite', + assert: [ + 'dist/components/banner/js/banner.js', + 'dist/components/banner/css/banner.css', + 'dist/components/banner/banner.twig', + 'dist/components/banner/banner.asset.txt', + ], + reject: ['components/banner/js/banner.js'], + }, + { + name: 'structure-implementations', + type: 'vite', + assert: [ + 'dist/js/button/button.js', + 'dist/css/button/button.css', + 'dist/components/button/button.twig', + 'dist/components/button/button.asset.txt', + 'dist/js/src/foundation/colors/colors.js', + 'dist/css/src/foundation/colors/colors.css', + 'dist/foundation/colors/palette.json', + 'dist/layout/grid/grid.twig', + 'dist/storybook/src/layout/grid/sb-grid.css', + 'dist/tokens/spacing/spacing.json', + ], + reject: ['components/button/button.js'], + }, + { + name: 'mixed-storybook', + type: 'storybook', + assert: ['.out/iframe.html'], + match: ['.out/assets/card.stories-*.js'], + }, + { + name: 'large-twig-storybook', + type: 'storybook', + setup: setupLargeTwigStorybookFixture, + assert: ['.out/iframe.html'], + match: ['.out/assets/gallery.stories-*.js'], + measure: true, + metricComponentCount: largeTwigComponentCount, + }, +]; + +function usage() { + return [ + 'Usage: node scripts/release-fixtures.js [--fixture ] [--list]', + '', + 'Options:', + ' --fixture Run one fixture by name. Can be repeated or comma-separated.', + ' --list Print fixture names and exit.', + ' --help Print this help text.', + ].join('\n'); +} + +function parseFixtureNames(value) { + return String(value || '') + .split(',') + .map((name) => name.trim()) + .filter(Boolean); +} + +function parseArgs(argv) { + const fixtureNames = []; + let list = false; + let help = false; + + for (let index = 0; index < argv.length; index += 1) { + const arg = argv[index]; + + if (arg === '--list') { + list = true; + continue; + } + if (arg === '--help' || arg === '-h') { + help = true; + continue; + } + if (arg === '--fixture') { + const value = argv[index + 1]; + if (!value || value.startsWith('--')) { + throw new Error('--fixture requires a fixture name.'); + } + fixtureNames.push(...parseFixtureNames(value)); + index += 1; + continue; + } + if (arg.startsWith('--fixture=')) { + fixtureNames.push(...parseFixtureNames(arg.slice('--fixture='.length))); + continue; + } + + throw new Error(`Unknown option: ${arg}`); + } + + return { fixtureNames, help, list }; +} + +function selectedFixtures(fixtureNames) { + if (!fixtureNames.length) { + return releaseFixtures; + } + + const fixturesByName = new Map( + releaseFixtures.map((fixture) => [fixture.name, fixture]), + ); + const selected = []; + + for (const fixtureName of fixtureNames) { + const fixture = fixturesByName.get(fixtureName); + if (!fixture) { + const available = releaseFixtures.map(({ name }) => name).join(', '); + throw new Error( + `Unknown fixture "${fixtureName}". Available: ${available}`, + ); + } + selected.push(fixture); + } + + return selected; +} + +function copyFixture(fixture) { + const { name, setup } = fixture; + const source = join(fixturesRoot, name); + const target = mkdtempSync(join(tmpdir(), `emulsify-core-${name}-`)); + cpSync(source, target, { recursive: true }); + if (typeof setup === 'function') { + setup(target); + } + linkFixturePackages(target); + return target; +} + +function setupLargeTwigStorybookFixture(projectDir) { + const componentsDir = join(projectDir, 'src/components'); + + for (let index = 1; index <= largeTwigComponentCount; index += 1) { + const id = String(index).padStart(3, '0'); + const componentName = `item-${id}`; + const componentDir = join(componentsDir, componentName); + mkdirSync(componentDir, { recursive: true }); + writeFileSync( + join(componentDir, `${componentName}.twig`), + [ + '
', + ` {{ include('@components/${componentName}/_content.twig', {`, + ` label: label|default('Item ${id}'),`, + ` index: ${index}`, + ' }) }}', + '
', + '', + ].join('\n'), + ); + writeFileSync( + join(componentDir, '_content.twig'), + [ + ``, + ' {{ label }} #{{ index }}', + '', + '', + ].join('\n'), + ); + } +} + +function linkFixturePackages(projectDir) { + const nodeModulesDir = join(projectDir, 'node_modules'); + const scopeDir = join(nodeModulesDir, '@emulsify'); + mkdirSync(scopeDir, { recursive: true }); + linkPackage(repoRoot, join(scopeDir, 'core')); + + for (const dependency of [ + '@storybook', + '@vitejs', + 'react', + 'react-dom', + 'storybook', + 'twig', + 'vite', + ]) { + linkPackage( + join(repoRoot, 'node_modules', dependency), + join(nodeModulesDir, dependency), + ); + } +} + +function linkPackage(source, target) { + try { + symlinkSync(source, target, 'junction'); + } catch (error) { + if (error.code !== 'EEXIST') { + throw error; + } + } +} + +function run(command, args, cwd) { + const result = spawnSync(command, args, { + cwd, + encoding: 'utf8', + env: { + ...process.env, + CI: '1', + FORCE_COLOR: '0', + NODE_OPTIONS: '--no-deprecation', + }, + }); + + if (result.status !== 0) { + process.stdout.write(result.stdout || ''); + process.stderr.write(result.stderr || ''); + throw new Error( + `${command} ${args.join(' ')} failed in ${cwd} with exit ${result.status}`, + ); + } + + return result; +} + +function assertExists(projectDir, relPaths) { + for (const relPath of relPaths) { + const absPath = join(projectDir, relPath); + if (!safeExists(absPath)) { + throw new Error(`Expected fixture output missing: ${relPath}`); + } + } +} + +function assertMissing(projectDir, relPaths = []) { + for (const relPath of relPaths) { + const absPath = join(projectDir, relPath); + if (safeExists(absPath)) { + throw new Error(`Unexpected fixture output exists: ${relPath}`); + } + } +} + +function assertMatches(projectDir, patterns = []) { + for (const pattern of patterns) { + const matches = globSync(pattern, { + cwd: projectDir, + nodir: true, + }); + if (!matches.length) { + throw new Error(`Expected fixture output pattern missing: ${pattern}`); + } + } +} + +function directorySize(directory) { + let total = 0; + + for (const entryName of readdirSync(directory)) { + const entryPath = join(directory, entryName); + const stats = statSync(entryPath); + if (stats.isDirectory()) { + total += directorySize(entryPath); + } else { + total += stats.size; + } + } + + return total; +} + +function formatBytes(bytes) { + const units = ['B', 'KB', 'MB', 'GB']; + let value = bytes; + let unitIndex = 0; + + while (value >= 1024 && unitIndex < units.length - 1) { + value /= 1024; + unitIndex += 1; + } + + return `${value.toFixed(unitIndex === 0 ? 0 : 1)} ${units[unitIndex]}`; +} + +function runViteFixture(fixture) { + const projectDir = copyFixture(fixture); + try { + console.log(`→ Running Vite fixture: ${fixture.name}`); + run( + process.execPath, + [viteBin, 'build', '--config', viteConfig], + projectDir, + ); + assertExists(projectDir, fixture.assert); + assertMissing(projectDir, fixture.reject); + console.log(`✓ Vite fixture passed: ${fixture.name}`); + } finally { + rmSync(projectDir, { recursive: true, force: true }); + } +} + +function runStorybookFixture(fixture) { + const projectDir = copyFixture(fixture); + const outputDir = join(projectDir, '.out'); + try { + console.log(`→ Running Storybook fixture: ${fixture.name}`); + const startedAt = process.hrtime.bigint(); + run( + storybookBin, + ['build', '--config-dir', storybookConfigDir, '-o', outputDir], + projectDir, + ); + const durationMs = Number(process.hrtime.bigint() - startedAt) / 1_000_000; + assertExists(projectDir, fixture.assert); + assertMatches(projectDir, fixture.match); + if (fixture.measure) { + const outputSize = directorySize(outputDir); + console.log( + ` Storybook metrics (${fixture.name}): ${(durationMs / 1000).toFixed( + 2, + )}s, ${formatBytes(outputSize)} output${ + fixture.metricComponentCount + ? `, ${fixture.metricComponentCount} generated Twig components` + : '' + }`, + ); + } + console.log(`✓ Storybook fixture passed: ${fixture.name}`); + } finally { + rmSync(projectDir, { recursive: true, force: true }); + } +} + +function runFixture(fixture) { + if (fixture.type === 'vite') { + runViteFixture(fixture); + return; + } + if (fixture.type === 'storybook') { + runStorybookFixture(fixture); + return; + } + + throw new Error( + `Unsupported fixture type "${fixture.type}" for ${fixture.name}.`, + ); +} + +try { + const options = parseArgs(process.argv.slice(2)); + + if (options.help) { + console.log(usage()); + process.exit(0); + } + if (options.list) { + console.log(releaseFixtures.map(({ name }) => name).join('\n')); + process.exit(0); + } + + const fixturesToRun = selectedFixtures(options.fixtureNames); + const label = + fixturesToRun.length === releaseFixtures.length + ? 'full release fixture suite' + : fixturesToRun.map(({ name }) => name).join(', '); + + console.log(`Running ${fixturesToRun.length} fixture(s): ${label}`); + for (const fixture of fixturesToRun) { + runFixture(fixture); + } +} catch (error) { + console.error(error.message || error); + console.error(''); + console.error(usage()); + process.exit(1); +} diff --git a/src/extensions/index.js b/src/extensions/index.js new file mode 100644 index 0000000..5ad9add --- /dev/null +++ b/src/extensions/index.js @@ -0,0 +1,8 @@ +/** + * @file Public extension namespace exports. + * @module extensions + */ + +// Keep extension families namespaced so new runtimes can be added safely. +export * as react from './react/index.js'; +export * as twig from './twig/index.js'; diff --git a/src/extensions/react/index.js b/src/extensions/react/index.js new file mode 100644 index 0000000..a1e824e --- /dev/null +++ b/src/extensions/react/index.js @@ -0,0 +1,12 @@ +/** + * @file Public exports for React extension helpers. + * @module extensions/react + * @reserved React extension registry behavior is not yet implemented. See + * `register.js` for the current no-op contract. + */ + +// Re-export from a single entry point for consumers and future registry growth. +export { + createReactExtensionRegistry, + defineReactExtension, +} from './register.js'; diff --git a/src/extensions/react/register.js b/src/extensions/react/register.js new file mode 100644 index 0000000..e4f24bf --- /dev/null +++ b/src/extensions/react/register.js @@ -0,0 +1,45 @@ +/** + * @file React extension registry placeholders. + * @module extensions/react/register + */ + +/** + * Return the provided React extension definition unchanged. + * + * @reserved Registry behavior is not yet implemented and may change in a + * future minor release. + * @example + * const extension = defineReactExtension({ + * name: 'project-react-components', + * components: {}, + * }); + * // Safe today: use `extension` directly instead of relying on registry side + * // effects. + * + * @param {Object} extension - React extension definition. + * @returns {Object} The provided extension definition. + */ +export function defineReactExtension(extension) { + // Keep this pass-through stable until React extensions need normalization. + return extension; +} + +/** + * Return React extension definitions after filtering falsy values. + * + * @reserved Registry behavior is not yet implemented and may change in a + * future minor release. + * @example + * const registry = createReactExtensionRegistry([ + * maybeExtension && defineReactExtension(maybeExtension), + * ]); + * // Safe today: read from `registry` directly instead of relying on runtime + * // registration. + * + * @param {Object[]} [extensions=[]] - Candidate extension definitions. + * @returns {Object[]} Filtered extension definitions. + */ +export function createReactExtensionRegistry(extensions = []) { + // Drop empty placeholders so callers can compose optional extension arrays. + return extensions.filter(Boolean); +} diff --git a/src/extensions/react/register.test.js b/src/extensions/react/register.test.js new file mode 100644 index 0000000..e5d8d38 --- /dev/null +++ b/src/extensions/react/register.test.js @@ -0,0 +1,36 @@ +/** + * @file Tests for reserved React extension helpers. + */ + +import { + createReactExtensionRegistry, + defineReactExtension, +} from './register.js'; + +describe('React extension helpers', () => { + it('returns the same React extension reference unchanged', () => { + const extension = { + name: 'project-react-components', + components: {}, + }; + + expect(defineReactExtension(extension)).toBe(extension); + }); + + it('filters falsy React extension registry values', () => { + const first = { name: 'first-extension' }; + const second = { name: 'second-extension' }; + + expect( + createReactExtensionRegistry([ + first, + null, + undefined, + false, + 0, + '', + second, + ]), + ).toEqual([first, second]); + }); +}); diff --git a/src/extensions/shared/attributes.js b/src/extensions/shared/attributes.js new file mode 100644 index 0000000..314b8d9 --- /dev/null +++ b/src/extensions/shared/attributes.js @@ -0,0 +1,308 @@ +/** + * @file Attribute serialization and composition utilities. + * @module extensions/shared/attributes + */ + +import { escapeAttributeValue, isSafeAttributeName } from './html.js'; +import { flattenList, uniqueList } from './lists.js'; +import { isPlainObject } from './object.js'; + +/** + * Cache cleaned class tokens because BEM class names repeat heavily across + * component renders during Storybook sessions. + * + * @type {Map} + */ +const classNameCache = new Map(); + +/** + * Brand AttributeBag instances without exposing a mutable marker property on + * the rendered object. + * + * @type {WeakSet} + */ +const attributeBags = new WeakSet(); + +/** + * Clean a single value into a CSS class token compatible with Twig.js output. + * + * @param {*} value - Candidate class token. + * @returns {string} Cleaned class token or an empty string. + */ +function cleanClassToken(value) { + const raw = String(value || '').trim(); + if (!raw) return ''; + + // Cache by raw input so repeated BEM renders avoid repeated regex work. + if (classNameCache.has(raw)) { + return classNameCache.get(raw); + } + + const cleaned = raw + .replace(/[^_a-zA-Z0-9-]+/g, '-') + .replace(/^-+|-+$/g, '') + .replace(/^([0-9])/, '_$1'); + + classNameCache.set(raw, cleaned); + return cleaned; +} + +/** + * Convert scalar, array, or AttributeBag values into clean class tokens. + * + * @param {*} value - Value containing one or more class names. + * @returns {string[]} Clean, unique class tokens. + */ +export function classTokensFromValue(value) { + if (isAttributeBag(value)) { + // AttributeBag class values are already normalized by this module. + return value.getClassList(); + } + + return uniqueList( + flattenList(value) + .flatMap((item) => String(item || '').split(/\s+/)) + .map((item) => cleanClassToken(item)) + .filter(Boolean), + ); +} + +/** + * Normalize non-class attribute values into serializable pieces. + * + * @param {*} value - Value to normalize. + * @returns {string|string[]|boolean|Object|null} Serializable value or null. + */ +function valueToAttributeParts(value) { + if (isAttributeBag(value)) { + // Preserve nested AttributeBag composition for helpers like add_attributes(). + return value.toObject(); + } + + if (value === null || typeof value === 'undefined' || value === false) { + return null; + } + + if (Array.isArray(value)) { + return flattenList(value) + .filter((item) => item !== null && typeof item !== 'undefined') + .map((item) => String(item)); + } + + if (typeof value === 'boolean') { + return value; + } + + if (typeof value === 'number' || typeof value === 'string') { + return String(value); + } + + if ( + typeof value?.toString === 'function' && + value.toString !== Object.prototype.toString + ) { + return String(value); + } + + return null; +} + +/** + * Extract class tokens from legacy `class="..."` strings. + * + * This keeps compatibility with old `bem()` string output without treating + * arbitrary `key=value` strings as trusted markup. + * + * @param {*} value - Potential legacy class attribute string. + * @returns {string|null} Raw class value when the string is class-only. + */ +function parseClassAttributeString(value) { + const match = String(value || '').match(/^class=(["'])(.*?)\1$/); + return match ? match[2] : null; +} + +/** + * Determine whether a value is an AttributeBag instance. + * + * @param {*} value - Value to inspect. + * @returns {boolean} TRUE when the value is branded by this module. + */ +export function isAttributeBag(value) { + return Boolean( + value && typeof value === 'object' && attributeBags.has(value), + ); +} + +/** + * Mutable HTML attribute collection with safe serialization. + * + * The class mirrors the tiny subset of Drupal's Attribute object needed by + * Storybook and Vite-rendered Twig templates. + */ +export class AttributeBag { + /** + * Create an attribute collection. + * + * @param {Object} [initialAttributes={}] - Initial attributes to merge. + */ + constructor(initialAttributes = {}) { + attributeBags.add(this); + this.attributes = new Map(); + + this.merge(initialAttributes); + } + + /** + * Create a copy of this collection. + * + * @returns {AttributeBag} New AttributeBag with equivalent attributes. + */ + clone() { + return new AttributeBag(this.toObject()); + } + + /** + * Get the normalized class list. + * + * @returns {string[]} Current class tokens. + */ + getClassList() { + return this.attributes.get('class') || []; + } + + /** + * Append one or more class tokens. + * + * @param {*} value - Class value to normalize and append. + * @returns {AttributeBag} Current instance for chaining. + */ + addClass(value) { + const tokens = classTokensFromValue(value); + if (!tokens.length) return this; + + const existing = this.attributes.get('class') || []; + this.attributes.set('class', uniqueList([...existing, ...tokens])); + return this; + } + + /** + * Set or merge an attribute. + * + * Class values are always merged. Other attributes replace existing values + * once they have been normalized and validated. + * + * @param {string} name - Attribute name. + * @param {*} value - Attribute value. + * @returns {AttributeBag} Current instance for chaining. + */ + set(name, value) { + const attributeName = String(name || '').trim(); + if (!isSafeAttributeName(attributeName)) return this; + + if (attributeName === 'class') { + // Legacy callers may still pass class="..." strings from old helpers. + const classString = + typeof value === 'string' ? parseClassAttributeString(value) : null; + this.addClass(classString || value); + return this; + } + + const normalizedValue = valueToAttributeParts(value); + if (normalizedValue === null) return this; + + this.attributes.set(attributeName, normalizedValue); + return this; + } + + /** + * Merge an object or another AttributeBag into this collection. + * + * @param {Object|AttributeBag} value - Attribute source. + * @returns {AttributeBag} Current instance for chaining. + */ + merge(value) { + if (!value) return this; + + if (isAttributeBag(value)) { + for (const [name, attributeValue] of value.attributes.entries()) { + this.set(name, attributeValue); + } + return this; + } + + if (!isPlainObject(value)) { + return this; + } + + for (const [name, attributeValue] of Object.entries(value)) { + if (name === '_keys') continue; + this.set(name, attributeValue); + } + + return this; + } + + /** + * Convert attributes to a plain object. + * + * @returns {Object} Plain attribute map. + */ + toObject() { + return Object.fromEntries(this.attributes.entries()); + } + + /** + * Serialize the attribute collection for direct Twig output. + * + * @returns {string} HTML-safe attribute string. + */ + toString() { + return Array.from(this.attributes.entries()) + .map(([name, value]) => { + if (name === 'class' && Array.isArray(value)) { + if (!value.length) return ''; + return `class="${escapeAttributeValue(value.join(' '))}"`; + } + + if (value === true) { + return name; + } + + if (Array.isArray(value)) { + return `${name}="${escapeAttributeValue(value.join(' '))}"`; + } + + return `${name}="${escapeAttributeValue(value)}"`; + }) + .filter(Boolean) + .join(' '); + } +} + +/** + * Build an AttributeBag from the current Twig invocation context. + * + * @param {Object} invocationContext - Twig.js function invocation `this`. + * @returns {AttributeBag} Attribute collection from context attributes. + */ +export function attributesFromContext(invocationContext) { + return new AttributeBag(invocationContext?.context?.attributes || {}); +} + +/** + * Clear context attributes after they have been consumed. + * + * Drupal removes attributes after printing them so they do not leak into child + * includes; this mirrors that behavior for Storybook and Vite rendering. + * + * @param {Object} invocationContext - Twig.js function invocation `this`. + * @returns {void} + */ +export function clearContextAttributes(invocationContext) { + if ( + invocationContext?.context && + Object.hasOwn(invocationContext.context, 'attributes') + ) { + invocationContext.context.attributes = {}; + } +} diff --git a/src/extensions/shared/html.js b/src/extensions/shared/html.js new file mode 100644 index 0000000..93dad50 --- /dev/null +++ b/src/extensions/shared/html.js @@ -0,0 +1,41 @@ +/** + * @file HTML escaping and attribute-name validation helpers. + * @module extensions/shared/html + */ + +const ATTRIBUTE_NAME_PATTERN = /^[A-Za-z_:][A-Za-z0-9:_.-]*$/; + +/** + * Determine whether a name is safe to print as an HTML attribute name. + * + * @param {string} name - Candidate attribute name. + * @returns {boolean} TRUE when the name can be safely serialized. + */ +export function isSafeAttributeName(name) { + // Reject spaces, quotes, and event-like malformed names before serialization. + return ATTRIBUTE_NAME_PATTERN.test(String(name || '')); +} + +/** + * Escape a value for use inside a double-quoted HTML attribute. + * + * @param {*} value - Attribute value to serialize. + * @returns {string} Escaped value. + */ +export function escapeAttributeValue(value) { + return String(value).replace(/[&"<>]/g, (character) => { + // Return the named entity for each unsafe character. + switch (character) { + case '&': + return '&'; + case '"': + return '"'; + case '<': + return '<'; + case '>': + return '>'; + default: + return character; + } + }); +} diff --git a/src/extensions/shared/lists.js b/src/extensions/shared/lists.js new file mode 100644 index 0000000..1eeeaaa --- /dev/null +++ b/src/extensions/shared/lists.js @@ -0,0 +1,38 @@ +/** + * @file List coercion utilities shared by extension implementations. + * @module extensions/shared/lists + */ + +import { unique } from '../../../config/vite/utils/unique.js'; + +export { unique }; + +/** + * Convert scalar or nested array values into a flat list. + * + * @param {*} value - Value to flatten. + * @returns {*[]} Flat list with null, undefined, and false treated as empty. + */ +export function flattenList(value) { + if (value === null || typeof value === 'undefined' || value === false) { + // Match Twig-style falsey class handling without discarding 0 or ''. + return []; + } + + if (!Array.isArray(value)) { + return [value]; + } + + return value.flatMap((item) => flattenList(item)); +} + +/** + * Return values in their first-seen order with duplicates removed. + * + * @param {*[]} values - Values to deduplicate. + * @returns {*[]} Unique values. + */ +export function uniqueList(values) { + // Preserve first-seen order; class order can affect utility CSS output. + return unique(values); +} diff --git a/src/extensions/shared/object.js b/src/extensions/shared/object.js new file mode 100644 index 0000000..5005d6a --- /dev/null +++ b/src/extensions/shared/object.js @@ -0,0 +1,22 @@ +/** + * @file Object type guards shared by extension implementations. + * @module extensions/shared/object + */ + +/** + * Determine whether a value is a plain object. + * + * Objects from Twig.js context data generally have either Object.prototype or + * a null prototype. Class instances are intentionally excluded so extension + * code does not accidentally treat rich objects as attribute maps. + * + * @param {*} value - Value to inspect. + * @returns {boolean} TRUE when the value is a plain object. + */ +export function isPlainObject(value) { + if (!value || typeof value !== 'object') return false; + + // Twig context maps may be created with null prototypes. + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; +} diff --git a/src/extensions/twig/__tests__/add-attributes.test.js b/src/extensions/twig/__tests__/add-attributes.test.js new file mode 100644 index 0000000..9ad5ac1 --- /dev/null +++ b/src/extensions/twig/__tests__/add-attributes.test.js @@ -0,0 +1,118 @@ +/** + * @file Tests for the native `add_attributes()` Twig helper. + */ + +import Twig from 'twig'; +import { addAttributes } from '../functions/add-attributes.js'; +import { bemAttributes } from '../functions/bem.js'; +import { registerTwigExtensions } from '../register.js'; + +/** + * Pure attribute builder coverage keeps serialization independent from Twig.js. + */ +describe('addAttributes', () => { + it('serializes scalar and list attributes', () => { + expect( + String( + addAttributes({ + class: ['foo', 'bar'], + baz: ['foobar', 'goobar'], + foobaz: 'goobaz', + }), + ), + ).toBe('class="foo bar" baz="foobar goobar" foobaz="goobaz"'); + }); + + it('composes with bem output without raw string parsing', () => { + expect( + String( + addAttributes({ + class: bemAttributes('foo', ['bar', 'baz'], 'foobar'), + }), + ), + ).toBe('class="foobar__foo foobar__foo--bar foobar__foo--baz"'); + }); + + it('escapes attribute values and ignores unsafe names', () => { + expect( + String( + addAttributes({ + title: '"quoted" & ', + 'bad attr': 'ignored', + }), + ), + ).toBe('title=""quoted" & <tag>"'); + }); + + it('renders true boolean attributes and skips falsey attributes', () => { + expect( + String( + addAttributes({ + disabled: true, + hidden: false, + inert: null, + draggable: 0, + }), + ), + ).toBe('disabled draggable="0"'); + }); + + /** + * Context merge coverage protects the Drupal-compatible print-once behavior. + */ + it('merges context attributes before additional attributes', () => { + const invocationContext = { + context: { + attributes: { + class: ['existing'], + id: 'card', + }, + }, + }; + + expect( + String( + addAttributes( + { class: ['new'], 'data-state': 'ready' }, + invocationContext, + ), + ), + ).toBe('class="existing new" id="card" data-state="ready"'); + // Context attributes are cleared after rendering to match Drupal output. + expect(invocationContext.context.attributes).toEqual({}); + }); +}); + +/** + * Twig.js registration coverage verifies the public template API. + */ +describe('registered add_attributes Twig function', () => { + it('renders in Twig.js templates', () => { + registerTwigExtensions(Twig); + + const template = Twig.twig({ + data: '
', + }); + + expect( + template.render({ + attrs: { + class: ['foo', 'bar'], + disabled: true, + }, + }), + ).toBe('
'); + }); + + it('accepts bem output in Twig.js templates', () => { + registerTwigExtensions(Twig); + + const template = Twig.twig({ + data: '
', + }); + + expect(template.render({})).toBe( + '
', + ); + }); +}); diff --git a/src/extensions/twig/__tests__/bem.test.js b/src/extensions/twig/__tests__/bem.test.js new file mode 100644 index 0000000..c60676d --- /dev/null +++ b/src/extensions/twig/__tests__/bem.test.js @@ -0,0 +1,101 @@ +/** + * @file Tests for the native `bem()` Twig helper. + */ + +import Twig from 'twig'; +import { AttributeBag } from '../../shared/attributes.js'; +import { bemAttributes } from '../functions/bem.js'; +import { registerTwigExtensions } from '../register.js'; + +/** + * Pure BEM builder coverage keeps class generation independent from Twig.js. + */ +describe('bemAttributes', () => { + it('builds a simple block class', () => { + expect(String(bemAttributes('title'))).toBe('class="title"'); + }); + + it('builds block modifiers', () => { + expect(String(bemAttributes('title', ['small', 'red']))).toBe( + 'class="title title--small title--red"', + ); + }); + + it('builds element classes with a block name', () => { + expect(String(bemAttributes('title', ['small', 'red'], 'card'))).toBe( + 'class="card__title card__title--small card__title--red"', + ); + }); + + it('adds extra non-BEM classes', () => { + expect( + String(bemAttributes('title', ['small'], 'card', ['js-click'])), + ).toBe('class="card__title card__title--small js-click"'); + }); + + it('supports object syntax for future extension readability', () => { + expect( + String( + bemAttributes({ + block: 'card', + element: 'title', + modifiers: ['small'], + extra: ['js-click'], + }), + ), + ).toBe('class="card__title card__title--small js-click"'); + }); + + it('deduplicates and cleans class names', () => { + expect( + String(bemAttributes('button', ['red!'], '', ['red!', 'button'])), + ).toBe('class="button button--red red"'); + }); + + it('merges explicit attributes', () => { + expect( + String( + bemAttributes('button', [], '', [], { id: 'primary', disabled: true }), + ), + ).toBe('id="primary" disabled class="button"'); + }); + + it('returns an AttributeBag for safe composition', () => { + expect(bemAttributes('button')).toBeInstanceOf(AttributeBag); + }); +}); + +/** + * Twig.js registration coverage verifies the public template API. + */ +describe('registered bem Twig function', () => { + it('renders in Twig.js templates', () => { + registerTwigExtensions(Twig); + + const template = Twig.twig({ + data: '

', + }); + + expect(template.render({})).toBe('

'); + }); + + it('merges and clears context attributes', () => { + registerTwigExtensions(Twig); + + const template = Twig.twig({ + data: '

', + }); + const context = { + attributes: { + class: ['from-context'], + id: 'headline', + }, + }; + + expect(template.render(context)).toBe( + '

', + ); + // Context attributes are consumed once to mirror Drupal template output. + expect(context.attributes).toEqual({}); + }); +}); diff --git a/src/extensions/twig/__tests__/register.test.js b/src/extensions/twig/__tests__/register.test.js new file mode 100644 index 0000000..2a244f5 --- /dev/null +++ b/src/extensions/twig/__tests__/register.test.js @@ -0,0 +1,50 @@ +/** + * @file Tests for native Twig extension registration. + */ + +import { getTwigFunctionMap } from '../function-map.js'; +import { getTwigTagDefinitions } from '../tag-map.js'; +import { registerTwigExtensions } from '../register.js'; + +describe('registerTwigExtensions', () => { + it('registers all native Twig extensions once per Twig instance', () => { + const InternalTwig = {}; + const Twig = { + extend: jest.fn((callback) => callback(InternalTwig)), + extendFunction: jest.fn(), + extendTag: jest.fn(), + }; + + // Calling twice should not duplicate Twig.js extension registration. + registerTwigExtensions(Twig); + registerTwigExtensions(Twig); + + const functionNames = Object.keys(getTwigFunctionMap()); + expect(Twig.extendFunction).toHaveBeenCalledTimes(functionNames.length); + + for (const name of functionNames) { + expect(Twig.extendFunction).toHaveBeenCalledWith( + name, + expect.any(Function), + ); + } + + const tagDefinitions = getTwigTagDefinitions(InternalTwig); + expect(Twig.extendTag).toHaveBeenCalledTimes(tagDefinitions.length); + + for (const definition of tagDefinitions) { + expect(Twig.extendTag).toHaveBeenCalledWith( + expect.objectContaining({ + type: definition.type, + regex: definition.regex, + }), + ); + } + }); + + it('requires a Twig.js-compatible instance', () => { + expect(() => registerTwigExtensions({})).toThrow( + 'A Twig.js instance with extendFunction(), extendTag(), and extend() is required.', + ); + }); +}); diff --git a/src/extensions/twig/__tests__/switch.test.js b/src/extensions/twig/__tests__/switch.test.js new file mode 100644 index 0000000..904f8ba --- /dev/null +++ b/src/extensions/twig/__tests__/switch.test.js @@ -0,0 +1,184 @@ +/** + * @file Tests for native Twig switch/case/default tags. + */ + +import Twig from 'twig'; +import { registerTwigExtensions } from '../register.js'; +import { splitSwitchCaseExpressions } from '../tags/switch.js'; + +/** + * Render a Twig string with native Emulsify extensions registered. + * + * @param {string} data - Twig template source. + * @param {Object} [context={}] - Twig render context. + * @returns {string} Rendered Twig output. + */ +function render(data, context = {}) { + registerTwigExtensions(Twig); + + return Twig.twig({ data }).render(context); +} + +describe('splitSwitchCaseExpressions', () => { + it('splits top-level or-delimited case values', () => { + expect( + splitSwitchCaseExpressions( + '\u0027alpha\u0027 or \u0027beta\u0027 or variant', + ), + ).toEqual(['\u0027alpha\u0027', '\u0027beta\u0027', 'variant']); + }); + + it('preserves or text inside strings and nested expressions', () => { + expect( + splitSwitchCaseExpressions( + '\u0027red or blue\u0027 or (fallback or alternate)', + ), + ).toEqual(['\u0027red or blue\u0027', '(fallback or alternate)']); + }); +}); + +describe('registered switch Twig tags', () => { + it('renders the matching case body', () => { + const output = render( + ` + {% switch value %} + {% case 'alpha' %} + Alpha + {% case 'beta' %} + Beta + {% endswitch %} + `, + { value: 'beta' }, + ); + + expect(output).toContain('Beta'); + expect(output).not.toContain('Alpha'); + }); + + it('supports multiple values on a case using or', () => { + const output = render( + ` + {% switch value %} + {% case 'alpha' or 'beta' %} + Matched + {% default %} + Default + {% endswitch %} + `, + { value: 'beta' }, + ); + + expect(output).toContain('Matched'); + expect(output).not.toContain('Default'); + }); + + it('renders default when no case matches', () => { + const output = render( + ` + {% switch value %} + {% case 'alpha' %} + Alpha + {% default %} + Default + {% endswitch %} + `, + { value: 'gamma' }, + ); + + expect(output).toContain('Default'); + expect(output).not.toContain('Alpha'); + }); + + it('returns no branch output when no case matches and no default exists', () => { + const output = render( + ` + Before + {% switch value %} + {% case 'alpha' %} + Alpha + {% endswitch %} + After + `, + { value: 'gamma' }, + ); + + expect(output).toContain('Before'); + expect(output).toContain('After'); + expect(output).not.toContain('Alpha'); + }); + + it('supports case expressions from render context', () => { + const output = render( + ` + {% switch value %} + {% case primary %} + Primary + {% case secondary %} + Secondary + {% endswitch %} + `, + { + primary: 'alpha', + secondary: 'beta', + value: 'beta', + }, + ); + + expect(output).toContain('Secondary'); + expect(output).not.toContain('Primary'); + }); + + it('uses PHP-style loose switch matching for scalar values', () => { + const output = render( + ` + {% switch value %} + {% case '2' %} + Numeric string + {% default %} + Default + {% endswitch %} + `, + { value: 2 }, + ); + + expect(output).toContain('Numeric string'); + expect(output).not.toContain('Default'); + }); + + it('renders only the first matching case body', () => { + const output = render( + ` + {% switch value %} + {% case 'beta' %} + First + {% case 'beta' %} + Second + {% default %} + Default + {% endswitch %} + `, + { value: 'beta' }, + ); + + expect(output).toContain('First'); + expect(output).not.toContain('Second'); + expect(output).not.toContain('Default'); + }); + + it('supports or text inside string case values', () => { + const output = render( + ` + {% switch value %} + {% case 'red or blue' or 'green' %} + Matched + {% default %} + Default + {% endswitch %} + `, + { value: 'red or blue' }, + ); + + expect(output).toContain('Matched'); + expect(output).not.toContain('Default'); + }); +}); diff --git a/src/extensions/twig/function-map.js b/src/extensions/twig/function-map.js new file mode 100644 index 0000000..67ce2c6 --- /dev/null +++ b/src/extensions/twig/function-map.js @@ -0,0 +1,20 @@ +/** + * @file Native Twig function map. + * @module extensions/twig/function-map + */ + +import { addAttributesTwigFunction } from './functions/add-attributes.js'; +import { bemTwigFunction } from './functions/bem.js'; + +/** + * Get Twig.js function definitions for native Emulsify helpers. + * + * @returns {Record} Function names keyed to Twig callbacks. + */ +export function getTwigFunctionMap() { + // Twig.js expects function names keyed to callable implementations. + return { + add_attributes: addAttributesTwigFunction, + bem: bemTwigFunction, + }; +} diff --git a/src/extensions/twig/functions/add-attributes.js b/src/extensions/twig/functions/add-attributes.js new file mode 100644 index 0000000..bc98484 --- /dev/null +++ b/src/extensions/twig/functions/add-attributes.js @@ -0,0 +1,39 @@ +/** + * @file Native `add_attributes()` Twig function implementation. + * @module extensions/twig/functions/add-attributes + */ + +import { + AttributeBag, + attributesFromContext, + clearContextAttributes, +} from '../../shared/attributes.js'; + +/** + * Merge additional attributes with attributes from the current Twig context. + * + * @param {Object} [additionalAttributes={}] - Attributes to add or merge. + * @param {Object} [invocationContext] - Twig.js function invocation `this`. + * @returns {AttributeBag} AttributeBag ready for Twig serialization. + */ +export function addAttributes(additionalAttributes = {}, invocationContext) { + // Context attributes are merged first so explicit additions can append safely. + const attributeBag = attributesFromContext(invocationContext); + attributeBag.merge(additionalAttributes); + clearContextAttributes(invocationContext); + + return attributeBag; +} + +/** + * Twig.js adapter for `add_attributes()`. + * + * @param {Object} [additionalAttributes={}] - Attributes to add or merge. + * @returns {AttributeBag} AttributeBag ready for Twig serialization. + */ +export function addAttributesTwigFunction(additionalAttributes = {}) { + // Preserve Twig.js' invocation context for Drupal-compatible attributes. + return addAttributes(additionalAttributes, this); +} + +export { AttributeBag }; diff --git a/src/extensions/twig/functions/bem.js b/src/extensions/twig/functions/bem.js new file mode 100644 index 0000000..4e7f482 --- /dev/null +++ b/src/extensions/twig/functions/bem.js @@ -0,0 +1,166 @@ +/** + * @file Native `bem()` Twig function implementation. + * @module extensions/twig/functions/bem + */ + +import { + AttributeBag, + attributesFromContext, + clearContextAttributes, +} from '../../shared/attributes.js'; +import { flattenList } from '../../shared/lists.js'; +import { isPlainObject } from '../../shared/object.js'; + +/** + * Normalize positional and object-style BEM arguments into one shape. + * + * @param {string|Object} baseClass - Base class or options object. + * @param {*[]} modifiers - Positional modifiers. + * @param {string} blockname - Positional block name. + * @param {*[]} extra - Positional extra classes. + * @param {Object} attributes - Positional extra attributes. + * @returns {{ + * baseClass: *, + * modifiers: *, + * blockname: *, + * extra: *, + * attributes: Object + * }} Normalized BEM options. + */ +function normalizeBemOptions( + baseClass, + modifiers, + blockname, + extra, + attributes, +) { + if (!isPlainObject(baseClass)) { + return { + baseClass, + modifiers, + blockname, + extra, + attributes, + }; + } + + const options = baseClass; + const hasBEMObjectShape = options.block && options.element; + + // Prefer explicit keys, then map block/element object syntax. + return { + baseClass: + options.baseClass || + options.base_class || + options.base || + (hasBEMObjectShape ? options.element : options.block), + modifiers: options.modifiers || [], + blockname: + options.blockname || + options.blockName || + (hasBEMObjectShape ? options.block : options.element) || + '', + extra: options.extra || [], + attributes: options.attributes || {}, + }; +} + +/** + * Convert an argument into a clean list while preserving string contents. + * + * Class-token sanitization happens later in AttributeBag so BEM composition can + * treat classes and attributes through one path. + * + * @param {*} value - Value to normalize. + * @returns {*[]} Flattened non-empty values. + */ +function normalizeList(value) { + return flattenList(value).filter((item) => { + return item !== null && typeof item !== 'undefined' && item !== ''; + }); +} + +/** + * Build BEM attributes. + * + * @param {string|Object} baseClass - Base class or object-style options. + * @param {*[]} [modifiers=[]] - Modifier values. + * @param {string} [blockname=''] - Block name for element output. + * @param {*[]} [extra=[]] - Non-BEM class values. + * @param {Object} [attributes={}] - Additional attributes. + * @param {Object} [invocationContext] - Twig.js function invocation `this`. + * @returns {AttributeBag} AttributeBag ready for Twig serialization. + */ +export function bemAttributes( + baseClass, + modifiers = [], + blockname = '', + extra = [], + attributes = {}, + invocationContext, +) { + const options = normalizeBemOptions( + baseClass, + modifiers, + blockname, + extra, + attributes, + ); + const normalizedBaseClass = String(options.baseClass || '').trim(); + const normalizedBlockname = String(options.blockname || '').trim(); + const classes = []; + + // Generate canonical BEM class names before adding non-BEM extras. + if (normalizedBaseClass) { + const classPrefix = normalizedBlockname + ? `${normalizedBlockname}__${normalizedBaseClass}` + : normalizedBaseClass; + + classes.push(classPrefix); + + for (const modifier of normalizeList(options.modifiers)) { + classes.push(`${classPrefix}--${modifier}`); + } + } + + classes.push(...normalizeList(options.extra)); + + const attributeBag = new AttributeBag(options.attributes); + attributeBag.addClass(classes); + + // Merge then clear context attributes to match Drupal's print-once model. + if (invocationContext?.context?.attributes) { + const contextAttributes = attributesFromContext(invocationContext); + attributeBag.merge(contextAttributes); + clearContextAttributes(invocationContext); + } + + return attributeBag; +} + +/** + * Twig.js adapter for `bem()`. + * + * @param {string|Object} baseClass - Base class or object-style options. + * @param {*[]} modifiers - Modifier values. + * @param {string} blockname - Block name for element output. + * @param {*[]} extra - Non-BEM class values. + * @param {Object} attributes - Additional attributes. + * @returns {AttributeBag} AttributeBag ready for Twig serialization. + */ +export function bemTwigFunction( + baseClass, + modifiers, + blockname, + extra, + attributes, +) { + return bemAttributes( + baseClass, + modifiers, + blockname, + extra, + attributes, + this, + ); +} diff --git a/src/extensions/twig/index.js b/src/extensions/twig/index.js new file mode 100644 index 0000000..5842c3e --- /dev/null +++ b/src/extensions/twig/index.js @@ -0,0 +1,13 @@ +/** + * @file Public exports for native Twig extensions. + * @module extensions/twig + */ + +// Export registry helpers before individual functions for the public API. +export { getTwigFunctionMap } from './function-map.js'; +export { registerTwigExtensions } from './register.js'; +export { + addAttributes, + addAttributesTwigFunction, +} from './functions/add-attributes.js'; +export { bemAttributes, bemTwigFunction } from './functions/bem.js'; diff --git a/src/extensions/twig/register.js b/src/extensions/twig/register.js new file mode 100644 index 0000000..a7a9c29 --- /dev/null +++ b/src/extensions/twig/register.js @@ -0,0 +1,52 @@ +/** + * @file Twig.js extension registration entry point. + * @module extensions/twig/register + */ + +import { getTwigFunctionMap } from './function-map.js'; +import { getTwigTagDefinitions } from './tag-map.js'; + +/** + * Twig instances that have already received native Emulsify extensions. + * + * @type {WeakSet} + */ +const registeredTwigInstances = new WeakSet(); + +/** + * Register native Emulsify Twig functions and logic tags with Twig.js. + * + * @param {Object} Twig - Twig.js module or compatible extension target. + * @returns {Object} The same Twig instance after registration. + * @throws {TypeError} When the provided value cannot register Twig extensions. + */ +export function registerTwigExtensions(Twig) { + if ( + !Twig || + typeof Twig.extendFunction !== 'function' || + typeof Twig.extendTag !== 'function' || + typeof Twig.extend !== 'function' + ) { + throw new TypeError( + 'A Twig.js instance with extendFunction(), extendTag(), and extend() is required.', + ); + } + + if (registeredTwigInstances.has(Twig)) { + return Twig; + } + + // Register once so repeated Storybook/Vite setup calls stay idempotent. + for (const [name, definition] of Object.entries(getTwigFunctionMap())) { + Twig.extendFunction(name, definition); + } + + Twig.extend((InternalTwig) => { + for (const definition of getTwigTagDefinitions(InternalTwig)) { + Twig.extendTag(definition); + } + }); + + registeredTwigInstances.add(Twig); + return Twig; +} diff --git a/src/extensions/twig/tag-map.js b/src/extensions/twig/tag-map.js new file mode 100644 index 0000000..411da28 --- /dev/null +++ b/src/extensions/twig/tag-map.js @@ -0,0 +1,16 @@ +/** + * @file Native Twig logic tag definitions. + * @module extensions/twig/tag-map + */ + +import { getSwitchTagDefinitions } from './tags/switch.js'; + +/** + * Get Twig.js logic tag definitions for native Emulsify helpers. + * + * @param {Object} Twig - Twig.js module or compatible extension target. + * @returns {Object[]} Logic tag definitions for Twig.extendTag(). + */ +export function getTwigTagDefinitions(Twig) { + return [...getSwitchTagDefinitions(Twig)]; +} diff --git a/src/extensions/twig/tags/switch.js b/src/extensions/twig/tags/switch.js new file mode 100644 index 0000000..0dc4cb0 --- /dev/null +++ b/src/extensions/twig/tags/switch.js @@ -0,0 +1,266 @@ +/** + * @file Native Twig.js switch/case/default logic tags. + * @module extensions/twig/tags/switch + */ + +const SWITCH_TAG_TYPE = 'emulsify_switch'; +const CASE_TAG_TYPE = 'emulsify_case'; +const DEFAULT_TAG_TYPE = 'emulsify_default'; +const ENDSWITCH_TAG_TYPE = 'emulsify_endswitch'; +const DOUBLE_QUOTE = '"'; +const SINGLE_QUOTE = '\u0027'; + +const OPENING_BRACKETS = new Set(['(', '[', '{']); +const CLOSING_BRACKETS = new Set([')', ']', '}']); + +/** + * Determine whether a character can be part of a Twig identifier. + * + * @param {string} [character] - Character to inspect. + * @returns {boolean} TRUE when the character is identifier-like. + */ +function isIdentifierCharacter(character) { + return Boolean(character && /[A-Za-z0-9_]/.test(character)); +} + +/** + * Split a case expression on top-level Twig `or` operators. + * + * Emulsify Tools uses `or` to express multiple PHP switch case values. Twig.js + * receives the full tag body as a string, so split only when `or` appears + * outside quotes and nested expressions. + * + * @param {string} expression - Raw `{% case ... %}` expression. + * @returns {string[]} One or more Twig expressions to compile as case values. + */ +export function splitSwitchCaseExpressions(expression) { + const parts = []; + let quote = null; + let escaped = false; + let depth = 0; + let start = 0; + + for (let index = 0; index < expression.length; index++) { + const character = expression.charAt(index); + + if (quote) { + if (escaped) { + escaped = false; + continue; + } + + if (character === '\\') { + escaped = true; + continue; + } + + if (character === quote) { + quote = null; + } + + continue; + } + + if (character === DOUBLE_QUOTE || character === SINGLE_QUOTE) { + quote = character; + continue; + } + + if (OPENING_BRACKETS.has(character)) { + depth += 1; + continue; + } + + if (CLOSING_BRACKETS.has(character)) { + depth = Math.max(0, depth - 1); + continue; + } + + if ( + depth === 0 && + expression.slice(index, index + 2) === 'or' && + !isIdentifierCharacter(expression.charAt(index - 1)) && + !isIdentifierCharacter(expression.charAt(index + 2)) + ) { + const part = expression.slice(start, index).trim(); + if (part) { + parts.push(part); + } + start = index + 2; + index += 1; + } + } + + const tail = expression.slice(start).trim(); + if (tail) { + parts.push(tail); + } + + return parts; +} + +/** + * Compile a Twig expression into a stack Twig.js can parse later. + * + * @param {Object} Twig - Twig.js module. + * @param {Object} state - Twig.js compile state. + * @param {string} value - Twig expression source. + * @returns {Object[]} Compiled expression stack. + */ +function compileExpression(Twig, state, value) { + return Twig.expression.compile.call(state, { + type: Twig.expression.type.expression, + value, + }).stack; +} + +/** + * Determine whether the current Twig logic chain belongs to an Emulsify switch. + * + * @param {*} chain - Twig.js logic chain value. + * @returns {boolean} TRUE when the chain was opened by `{% switch %}`. + */ +function isSwitchChain(chain) { + return Boolean(chain && chain.emulsifySwitch); +} + +/** + * Compare switch values using PHP-style loose switch semantics. + * + * @param {*} switchValue - Evaluated `{% switch ... %}` value. + * @param {*} caseValue - Evaluated `{% case ... %}` value. + * @returns {boolean} TRUE when the case matches. + */ +function isSwitchMatch(switchValue, caseValue) { + // PHP switch statements use loose equality; mirror that for Drupal parity. + return switchValue == caseValue; +} + +/** + * Render a token body and preserve the current switch chain. + * + * @param {Object} Twig - Twig.js module. + * @param {Object} state - Twig.js parse state. + * @param {Object} token - Compiled Twig.js logic token. + * @param {Object} context - Twig render context. + * @param {Object} chain - Active switch chain. + * @returns {Object|Promise} Twig.js logic parse result. + */ +function renderSwitchBranch(Twig, state, token, context, chain) { + return state.parseAsync(token.output || [], context).then((output) => ({ + chain, + output, + })); +} + +/** + * Create Twig.js logic tag definitions for switch/case/default/endswitch. + * + * @param {Object} Twig - Twig.js module or compatible extension target. + * @returns {Object[]} Logic tag definitions. + */ +export function getSwitchTagDefinitions(Twig) { + return [ + { + type: SWITCH_TAG_TYPE, + regex: /^switch\s+([\s\S]+)$/, + next: [CASE_TAG_TYPE, DEFAULT_TAG_TYPE, ENDSWITCH_TAG_TYPE], + open: true, + compile(token) { + token.stack = compileExpression(Twig, this, token.match[1]); + delete token.match; + return token; + }, + parse(token, context) { + const state = this; + + return Twig.expression.parseAsync + .call(state, token.stack, context) + .then((value) => ({ + chain: { + emulsifySwitch: true, + matched: false, + value, + }, + output: '', + })); + }, + }, + { + type: CASE_TAG_TYPE, + regex: /^case\s+([\s\S]+)$/, + next: [CASE_TAG_TYPE, DEFAULT_TAG_TYPE, ENDSWITCH_TAG_TYPE], + open: false, + compile(token) { + token.stacks = splitSwitchCaseExpressions(token.match[1]).map( + (expression) => compileExpression(Twig, this, expression), + ); + delete token.match; + return token; + }, + parse(token, context, chain) { + const state = this; + + if (!isSwitchChain(chain)) { + throw new Twig.Error('{% case %} must be used inside {% switch %}.'); + } + + if (chain.matched) { + return { + chain, + output: '', + }; + } + + return Twig.Promise.all( + token.stacks.map((stack) => + Twig.expression.parseAsync.call(state, stack, context), + ), + ).then((values) => { + if ( + !values.some((caseValue) => isSwitchMatch(chain.value, caseValue)) + ) { + return { + chain, + output: '', + }; + } + + chain.matched = true; + return renderSwitchBranch(Twig, state, token, context, chain); + }); + }, + }, + { + type: DEFAULT_TAG_TYPE, + regex: /^default$/, + next: [ENDSWITCH_TAG_TYPE], + open: false, + parse(token, context, chain) { + const state = this; + + if (!isSwitchChain(chain)) { + throw new Twig.Error( + '{% default %} must be used inside {% switch %}.', + ); + } + + if (chain.matched) { + return { + chain, + output: '', + }; + } + + chain.matched = true; + return renderSwitchBranch(Twig, state, token, context, chain); + }, + }, + { + type: ENDSWITCH_TAG_TYPE, + regex: /^endswitch$/, + next: [], + open: false, + }, + ]; +} diff --git a/src/storybook/__fixtures__/mixed-card.twig b/src/storybook/__fixtures__/mixed-card.twig new file mode 100644 index 0000000..a193cb2 --- /dev/null +++ b/src/storybook/__fixtures__/mixed-card.twig @@ -0,0 +1,10 @@ +
+

{{ heading }}

+

{{ body }}

+ {% switch variant|default('standard') %} + {% case 'featured' or 'highlight' %} + Featured + {% default %} + Standard + {% endswitch %} +
diff --git a/src/storybook/__fixtures__/mixed-renderers.stories.js b/src/storybook/__fixtures__/mixed-renderers.stories.js new file mode 100644 index 0000000..7fefab3 --- /dev/null +++ b/src/storybook/__fixtures__/mixed-renderers.stories.js @@ -0,0 +1,34 @@ +/** + * @file Storybook smoke stories covering Twig and React renderers together. + */ + +import React from 'react'; +import { renderTwig } from '@emulsify/core/storybook'; +import template from './mixed-card.twig'; + +export default { + title: 'Examples/Mixed Renderers', +}; + +export const TwigCard = { + render: renderTwig(template), + args: { + heading: 'Twig card', + body: 'Rendered through @emulsify/core/storybook.', + variant: 'featured', + }, +}; + +export const ReactCard = { + render: ({ heading, body }) => + React.createElement( + 'article', + { 'data-renderer': 'react' }, + React.createElement('h2', null, heading), + React.createElement('p', null, body), + ), + args: { + heading: 'React card', + body: 'Rendered as a normal React story.', + }, +}; diff --git a/src/storybook/index.js b/src/storybook/index.js new file mode 100644 index 0000000..07ab577 --- /dev/null +++ b/src/storybook/index.js @@ -0,0 +1,14 @@ +/** + * @file Public Storybook helpers for Emulsify Core. + * @module storybook + */ + +export { + getActiveStorybookAdapter, + renderHtmlStoryResult, + renderTwig, + renderTwigHtml, + renderTwigToHtml, + TwigHtmlStory, + TwigStory, +} from './render-twig.js'; diff --git a/src/storybook/main-config.js b/src/storybook/main-config.js new file mode 100644 index 0000000..d265cdf --- /dev/null +++ b/src/storybook/main-config.js @@ -0,0 +1,132 @@ +/** + * @file Helpers for applying project Storybook main configuration overrides. + */ + +/** + * Identify a Storybook addon so project config can override default addon + * options without duplicating the addon in the final list. + * + * @param {string|{name?: string}} addon - Storybook addon entry. + * @returns {string|null} Stable addon key when available. + */ +function addonKey(addon) { + if (typeof addon === 'string') return addon; + if (addon && typeof addon.name === 'string') return addon.name; + return null; +} + +/** + * Merge Storybook addon lists while preserving default addon order. + * + * Project addons are appended by default. When a project provides an addon with + * the same package name as a default addon, its entry replaces the default so + * projects can configure default addons without creating duplicates. + * + * @param {Array} defaults - Emulsify Core default addons. + * @param {Array} overrides - Project-provided addons. + * @param {{ replace?: boolean }} [options] - Whether overrides replace defaults. + * @returns {Array} Final addon list. + */ +export function mergeStorybookAddons( + defaults = [], + overrides = [], + { replace = false } = {}, +) { + if (replace) return [...overrides]; + + const merged = [...defaults]; + const indexesByKey = new Map(); + + merged.forEach((addon, index) => { + const key = addonKey(addon); + if (key) indexesByKey.set(key, index); + }); + + for (const addon of overrides) { + const key = addonKey(addon); + const existingIndex = key ? indexesByKey.get(key) : undefined; + if (existingIndex !== undefined) { + merged.splice(existingIndex, 1, addon); + continue; + } + + if (key) indexesByKey.set(key, merged.length); + merged.push(addon); + } + + return merged; +} + +/** + * Normalize an optional project `config/emulsify-core/storybook/main.js` module. + * + * @param {object} [module] - ESM module namespace loaded from the project. + * @returns {{ config: object|Function, extendConfig?: Function, replaceAddons: boolean }} + * Normalized override details. + */ +export function normalizeStorybookConfigOverrideModule(module = {}) { + const config = module.default || {}; + + return { + config, + extendConfig: + typeof module.extendConfig === 'function' + ? module.extendConfig + : undefined, + replaceAddons: module.replaceAddons === true, + }; +} + +/** + * Apply project Storybook main config overrides to Emulsify's default config. + * + * Default-exported override objects are shallow-merged, except `addons`, which + * are appended by default. Export `replaceAddons = true` or include + * `replaceAddons: true` in the default config object when full replacement is + * needed. Named `extendConfig()` runs last for advanced cases. + * + * @param {object} baseConfig - Emulsify Core Storybook config. + * @param {{ config?: object|Function, extendConfig?: Function, replaceAddons?: boolean }} [overrides] + * Project override details. + * @param {object} [context] - Context passed to config factories. + * @returns {Promise} Final Storybook config. + */ +export async function applyStorybookConfigOverrides( + baseConfig, + overrides = {}, + context = {}, +) { + const rawConfig = + typeof overrides.config === 'function' + ? await overrides.config(context) + : overrides.config; + const plainConfig = + rawConfig && typeof rawConfig === 'object' ? { ...rawConfig } : {}; + const configReplaceAddons = plainConfig.replaceAddons === true; + delete plainConfig.replaceAddons; + delete plainConfig.extendConfig; + const replaceAddons = overrides.replaceAddons || configReplaceAddons === true; + + let merged = { + ...baseConfig, + ...plainConfig, + }; + + if (Array.isArray(plainConfig.addons)) { + merged = { + ...merged, + addons: mergeStorybookAddons(baseConfig.addons, plainConfig.addons, { + replace: replaceAddons, + }), + }; + } + + if (typeof overrides.extendConfig === 'function') { + const extended = await overrides.extendConfig(merged, context); + if (extended && typeof extended === 'object') { + merged = extended; + } + } + + return merged; +} diff --git a/src/storybook/main-config.test.js b/src/storybook/main-config.test.js new file mode 100644 index 0000000..e8282af --- /dev/null +++ b/src/storybook/main-config.test.js @@ -0,0 +1,127 @@ +/** + * @file Tests for Storybook main configuration override helpers. + */ + +import { + applyStorybookConfigOverrides, + mergeStorybookAddons, + normalizeStorybookConfigOverrideModule, +} from './main-config.js'; + +describe('Storybook main config overrides', () => { + const baseConfig = { + addons: [ + '@storybook/addon-a11y', + '@storybook/addon-links', + '@storybook/addon-themes', + ], + framework: { + name: '@storybook/react-vite', + options: {}, + }, + }; + + it('appends project addons after Emulsify defaults', () => { + expect( + mergeStorybookAddons(baseConfig.addons, ['@storybook/addon-viewport']), + ).toEqual([ + '@storybook/addon-a11y', + '@storybook/addon-links', + '@storybook/addon-themes', + '@storybook/addon-viewport', + ]); + }); + + it('replaces default addon entries with project options for the same addon', () => { + expect( + mergeStorybookAddons(baseConfig.addons, [ + { + name: '@storybook/addon-a11y', + options: { manual: true }, + }, + ]), + ).toEqual([ + { + name: '@storybook/addon-a11y', + options: { manual: true }, + }, + '@storybook/addon-links', + '@storybook/addon-themes', + ]); + }); + + it('can replace the default addon list when requested', () => { + expect( + mergeStorybookAddons(baseConfig.addons, ['@storybook/addon-viewport'], { + replace: true, + }), + ).toEqual(['@storybook/addon-viewport']); + }); + + it('normalizes project main override modules', () => { + const extendConfig = jest.fn(); + + expect( + normalizeStorybookConfigOverrideModule({ + default: { addons: ['example-addon'] }, + extendConfig, + replaceAddons: true, + }), + ).toEqual({ + config: { addons: ['example-addon'] }, + extendConfig, + replaceAddons: true, + }); + }); + + it('applies addon and config overrides without dropping defaults', async () => { + await expect( + applyStorybookConfigOverrides(baseConfig, { + config: { + addons: ['@storybook/addon-viewport'], + docs: { autodocs: true }, + }, + }), + ).resolves.toEqual({ + ...baseConfig, + addons: [ + '@storybook/addon-a11y', + '@storybook/addon-links', + '@storybook/addon-themes', + '@storybook/addon-viewport', + ], + docs: { autodocs: true }, + }); + }); + + it('passes context to config factories and extendConfig', async () => { + const env = { platform: 'generic' }; + const extendConfig = jest.fn((config, context) => ({ + ...config, + staticDirs: [context.env.platform], + })); + + await expect( + applyStorybookConfigOverrides( + baseConfig, + { + config: ({ env: contextEnv }) => ({ + addons: [`addon-${contextEnv.platform}`], + }), + extendConfig, + }, + { env }, + ), + ).resolves.toEqual({ + ...baseConfig, + addons: [ + '@storybook/addon-a11y', + '@storybook/addon-links', + '@storybook/addon-themes', + 'addon-generic', + ], + staticDirs: ['generic'], + }); + expect(extendConfig).toHaveBeenCalled(); + }); +}); diff --git a/src/storybook/platform-behaviors.js b/src/storybook/platform-behaviors.js new file mode 100644 index 0000000..3eb9b88 --- /dev/null +++ b/src/storybook/platform-behaviors.js @@ -0,0 +1,59 @@ +/** + * @file Platform-specific Storybook behavior helpers. + */ + +export const genericStorybookAdapter = { + loadDrupalBehaviorShim: false, + attachDrupalBehaviors: false, + registerDrupalTwigFilters: false, + loadMirroredComponentCss: false, +}; + +/** + * Normalize optional platform adapter flags into the full Storybook shape. + * + * @param {object} [adapter] - Candidate Storybook adapter flags. + * @returns {object} Storybook adapter flags with generic defaults. + */ +export function normalizeStorybookPlatformAdapter(adapter = {}) { + return { + ...genericStorybookAdapter, + ...(adapter || {}), + }; +} + +/** + * Attach platform-specific behaviors after a Storybook render. + * + * Drupal behavior attachment is opt-in through the active platform adapter. + * Generic and unknown platforms return without creating Drupal globals. + * + * @param {object} [options={}] - Attachment options. + * @param {object} [options.adapter] - Active Storybook platform adapter. + * @param {Promise} [options.behaviorShimReady] - Optional behavior shim import. + * @param {HTMLElement|Document} [options.context] - Behavior attachment root. + * @param {object} [options.settings] - Behavior settings. + * @returns {Promise} TRUE when Drupal attachBehaviors ran. + */ +export async function attachStorybookBehaviors(options = {}) { + const adapter = normalizeStorybookPlatformAdapter(options.adapter); + if (!adapter.attachDrupalBehaviors) { + return false; + } + + await (options.behaviorShimReady || Promise.resolve()); + + const browserWindow = globalThis.window; + const drupal = browserWindow?.Drupal || globalThis.Drupal; + if (typeof drupal?.attachBehaviors !== 'function') { + return false; + } + + drupal.attachBehaviors( + options.context, + options.settings || + browserWindow?.drupalSettings || + globalThis.drupalSettings, + ); + return true; +} diff --git a/src/storybook/platform-behaviors.test.js b/src/storybook/platform-behaviors.test.js new file mode 100644 index 0000000..9d56d25 --- /dev/null +++ b/src/storybook/platform-behaviors.test.js @@ -0,0 +1,70 @@ +/** + * @file Tests for Storybook platform behavior helpers. + */ + +import { + attachStorybookBehaviors, + normalizeStorybookPlatformAdapter, +} from './platform-behaviors.js'; + +describe('Storybook platform behavior helpers', () => { + afterEach(() => { + delete window.Drupal; + delete window.drupalSettings; + }); + + it('attaches Drupal behaviors when the adapter enables Drupal support', async () => { + const context = document.createElement('main'); + window.drupalSettings = { path: { currentPath: '/storybook' } }; + window.Drupal = { + attachBehaviors: jest.fn(), + }; + + const attached = await attachStorybookBehaviors({ + adapter: { attachDrupalBehaviors: true }, + context, + }); + + expect(attached).toBe(true); + expect(window.Drupal.attachBehaviors).toHaveBeenCalledWith( + context, + window.drupalSettings, + ); + }); + + it('does not attach or create Drupal globals for generic platforms', async () => { + const attached = await attachStorybookBehaviors({ + adapter: { attachDrupalBehaviors: false }, + }); + + expect(attached).toBe(false); + expect(window.Drupal).toBeUndefined(); + }); + + it('does not throw when Drupal is absent and attachment is disabled', async () => { + await expect( + attachStorybookBehaviors({ + adapter: normalizeStorybookPlatformAdapter(), + }), + ).resolves.toBe(false); + expect(window.Drupal).toBeUndefined(); + }); + + it('waits for the Drupal behavior shim before attaching behaviors', async () => { + const attach = jest.fn(); + const behaviorShimReady = Promise.resolve().then(() => { + window.Drupal = { + attachBehaviors: attach, + }; + window.drupalSettings = {}; + }); + + const attached = await attachStorybookBehaviors({ + adapter: { attachDrupalBehaviors: true }, + behaviorShimReady, + }); + + expect(attached).toBe(true); + expect(attach).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/storybook/preview-parameters.js b/src/storybook/preview-parameters.js new file mode 100644 index 0000000..ad4ad6d --- /dev/null +++ b/src/storybook/preview-parameters.js @@ -0,0 +1,81 @@ +/** + * @file Storybook preview parameter override helpers. + */ + +/** + * Determine whether a value is a plain object suitable for recursive merging. + * + * @param {*} value - Candidate value. + * @returns {boolean} TRUE when value is a plain object. + */ +function isPlainObject(value) { + return ( + Boolean(value) && + Object.prototype.toString.call(value) === '[object Object]' + ); +} + +/** + * Merge Storybook preview parameters while preserving nested defaults. + * + * Arrays and non-object values are intentionally replaced by overrides. Plain + * objects merge recursively so partial `a11y.config` overrides keep defaults + * such as the enabled rule list unless a project explicitly replaces them. + * + * @param {object} [defaults={}] - Default Storybook parameters. + * @param {object} [overrides={}] - Project override parameters. + * @returns {object} Merged parameters. + */ +export function mergePreviewParameters(defaults = {}, overrides = {}) { + const merged = { ...defaults }; + + for (const [key, value] of Object.entries(overrides || {})) { + if (value === undefined) continue; + + // Storybook parameter keys are intentionally dynamic. + // eslint-disable-next-line security/detect-object-injection + const current = merged[key]; + const nextValue = + isPlainObject(current) && isPlainObject(value) + ? mergePreviewParameters(current, value) + : value; + + // Storybook parameter keys are intentionally dynamic. + // eslint-disable-next-line security/detect-object-injection + merged[key] = nextValue; + } + + return merged; +} + +/** + * Extract parameter overrides from a Vite-imported project preview module. + * + * Supports both direct parameter objects: + * export default { layout: 'centered' } + * + * And Storybook-shaped modules: + * export const parameters = { layout: 'centered' } + * export default { parameters: { layout: 'centered' } } + * + * @param {object} [module] - Imported preview override module. + * @returns {object} Preview parameter overrides. + */ +export function normalizePreviewOverrideModule(module = {}) { + const defaultExport = module?.default; + + if (isPlainObject(module?.parameters)) { + return module.parameters; + } + if (isPlainObject(defaultExport?.parameters)) { + return defaultExport.parameters; + } + if (isPlainObject(defaultExport)) { + return defaultExport; + } + if (isPlainObject(module)) { + return module; + } + + return {}; +} diff --git a/src/storybook/preview-parameters.test.js b/src/storybook/preview-parameters.test.js new file mode 100644 index 0000000..804aed9 --- /dev/null +++ b/src/storybook/preview-parameters.test.js @@ -0,0 +1,89 @@ +/** + * @file Tests for Storybook preview parameter override helpers. + */ + +import { + mergePreviewParameters, + normalizePreviewOverrideModule, +} from './preview-parameters.js'; + +describe('preview parameter overrides', () => { + const defaultParams = { + actions: { argTypesRegex: '^on[A-Z].*' }, + a11y: { + config: { + detailedReport: true, + detailedReportOptions: { html: true }, + rules: [{ id: 'color-contrast', enabled: true }], + }, + }, + layout: 'fullscreen', + }; + + it('keeps defaults when no preview override module is present', () => { + expect(mergePreviewParameters(defaultParams, undefined)).toEqual( + defaultParams, + ); + expect(normalizePreviewOverrideModule()).toEqual({}); + }); + + it('normalizes default-exported parameter objects', () => { + expect( + normalizePreviewOverrideModule({ + default: { + layout: 'centered', + }, + }), + ).toEqual({ layout: 'centered' }); + }); + + it('normalizes Storybook-shaped parameter exports', () => { + expect( + normalizePreviewOverrideModule({ + parameters: { + layout: 'padded', + }, + }), + ).toEqual({ layout: 'padded' }); + + expect( + normalizePreviewOverrideModule({ + default: { + parameters: { + layout: 'centered', + }, + }, + }), + ).toEqual({ layout: 'centered' }); + }); + + it('merges layout overrides without dropping default a11y parameters', () => { + expect( + mergePreviewParameters(defaultParams, { layout: 'centered' }), + ).toEqual({ + ...defaultParams, + layout: 'centered', + }); + }); + + it('allows a11y settings to be overridden while preserving nested defaults', () => { + expect( + mergePreviewParameters(defaultParams, { + a11y: { + config: { + detailedReport: false, + }, + }, + }), + ).toEqual({ + ...defaultParams, + a11y: { + config: { + detailedReport: false, + detailedReportOptions: { html: true }, + rules: [{ id: 'color-contrast', enabled: true }], + }, + }, + }); + }); +}); diff --git a/src/storybook/render-twig.js b/src/storybook/render-twig.js new file mode 100644 index 0000000..75d9835 --- /dev/null +++ b/src/storybook/render-twig.js @@ -0,0 +1,280 @@ +/** + * @file React Storybook renderer for imported Twig template modules. + */ + +import React, { useEffect, useLayoutEffect, useRef } from 'react'; +import { + attachStorybookBehaviors, + normalizeStorybookPlatformAdapter, +} from './platform-behaviors.js'; + +/** + * Read the normalized Emulsify environment injected by Storybook's Vite config. + * + * @returns {object} Injected Emulsify environment, when present. + */ +function getInjectedEnvironment() { + return globalThis.__EMULSIFY_ENV__ || {}; +} + +/** + * Normalize either a full platform adapter or the storybook adapter subset. + * + * @param {object} [adapter] - Candidate platform adapter. + * @returns {object} Storybook adapter flags. + */ +export function getActiveStorybookAdapter(options = {}) { + const adapter = + options.platformAdapter || getInjectedEnvironment().platformAdapter; + return normalizeStorybookPlatformAdapter(adapter?.storybook || adapter); +} + +/** + * Build Twig context from Storybook args and optional static defaults. + * + * @param {object} [args={}] - Storybook args. + * @param {{ context?: object|Function }} [options={}] - Render options. + * @param {object} [storyContext={}] - Storybook story context. + * @returns {object} Twig render context. + */ +function buildTwigContext(args = {}, options = {}, storyContext = {}) { + if (typeof options.context === 'function') { + return options.context(args, storyContext) || {}; + } + + return { + ...(options.context || {}), + ...(args || {}), + }; +} + +/** + * Check whether a string looks like rendered HTML markup. + * + * @param {*} value - Candidate story result. + * @returns {boolean} TRUE when the value appears to be an HTML string. + */ +function isLikelyHtmlString(value) { + return ( + typeof value === 'string' && + /^\s*<(?:!doctype|!--|[a-z][\w:-]*)(?:\s|>|\/)/i.test(value) + ); +} + +/** + * Convert a wrapper containing one raw HTML text node into real DOM markup. + * + * Storybook React may render string-returning legacy Twig stories as escaped + * text before decorators can inspect the string. This keeps those stories + * working without changing how normal React stories render. + * + * @param {HTMLElement} wrapper - Story wrapper element. + * @returns {boolean} TRUE when raw HTML text was converted. + */ +export function normalizeHtmlTextStory(wrapper) { + if (!wrapper || wrapper.childNodes.length !== 1) { + return false; + } + + const [onlyChild] = wrapper.childNodes; + if (onlyChild.nodeType !== Node.TEXT_NODE) { + return false; + } + + const html = onlyChild.textContent || ''; + if (!isLikelyHtmlString(html)) { + return false; + } + + wrapper.innerHTML = html; + wrapper.setAttribute('data-emulsify-twig-story', ''); + return true; +} + +/** + * Give Storybook's React element wrapper a useful string representation. + * + * Some legacy stories include decorators like `(story) => `${story()}``. + * Storybook React now passes those decorators a React element, which normally + * stringifies to `[object Object]`. This preserves the old behavior for Twig + * string stories while leaving the element renderable by React. + * + * @param {*} result - Candidate React story element. + * @param {Function} getStoryResult - Function returning the raw story result. + * @returns {*} Original or cloned story result. + */ +export function withLegacyStoryToString(result, getStoryResult) { + if (!React.isValidElement(result) || typeof getStoryResult !== 'function') { + return result; + } + + const element = { ...result }; + Object.defineProperty(element, 'toString', { + value: () => { + try { + const storyResult = getStoryResult(); + return storyResult == null ? '' : String(storyResult); + } catch { + return Object.prototype.toString.call(result); + } + }, + }); + + return element; +} + +/** + * Render an imported Twig module into an HTML string. + * + * @param {Function} template - Twig render function. + * @param {object} [args={}] - Storybook args. + * @param {object} [options={}] - Render options. + * @param {object} [storyContext={}] - Storybook story context. + * @returns {string} Rendered HTML. + */ +export function renderTwigToHtml( + template, + args = {}, + options = {}, + storyContext = {}, +) { + if (typeof template !== 'function') { + return ''; + } + + try { + const html = template(buildTwigContext(args, options, storyContext)); + return html == null ? '' : String(html); + } catch (error) { + return `An error occurred whilst rendering Twig story: ${ + error?.message || error + }`; + } +} + +/** + * React component that renders an HTML string into a stable wrapper element. + * + * @param {object} props - Component props. + * @param {string} [props.html] - Rendered HTML string. + * @param {object} [props.options] - Render options. + * @returns {React.ReactElement} React element. + */ +export function TwigHtmlStory({ html = '', options = {} }) { + const wrapperRef = useRef(null); + const adapter = getActiveStorybookAdapter(options); + const Wrapper = options.wrapper || 'div'; + + useEffect(() => { + void attachStorybookBehaviors({ + adapter, + context: wrapperRef.current, + }); + }, [adapter.attachDrupalBehaviors, html]); + + return React.createElement(Wrapper, { + ref: wrapperRef, + id: options.id, + className: options.className, + 'data-emulsify-twig-story': '', + dangerouslySetInnerHTML: { __html: html }, + }); +} + +/** + * Boundary that repairs legacy string-returning stories rendered as React text. + * + * @param {object} props - Component props. + * @param {*} props.children - Rendered Storybook story result. + * @returns {React.ReactElement} React element. + */ +export function StoryHtmlBoundary({ children }) { + const wrapperRef = useRef(null); + + useLayoutEffect(() => { + normalizeHtmlTextStory(wrapperRef.current); + }, [children]); + + return React.createElement( + 'div', + { + ref: wrapperRef, + 'data-emulsify-story-boundary': '', + style: { display: 'contents' }, + }, + children, + ); +} + +/** + * React component that renders Twig HTML into a stable wrapper element. + * + * @param {object} props - Component props. + * @param {Function} props.template - Twig render function. + * @param {object} [props.args] - Storybook args. + * @param {object} [props.options] - Render options. + * @param {object} [props.storyContext] - Storybook story context. + * @returns {React.ReactElement} React element. + */ +export function TwigStory({ + template, + args = {}, + options = {}, + storyContext = {}, +}) { + return React.createElement(TwigHtmlStory, { + html: renderTwigToHtml(template, args, options, storyContext), + options, + }); +} + +/** + * Render a raw HTML string through the same wrapper used by Twig stories. + * + * This supports legacy Storybook stories that return Twig HTML strings + * directly while projects migrate to `renderTwig()`. + * + * @param {string} html - Rendered HTML. + * @param {object} [options={}] - Render options. + * @returns {React.ReactElement} React element. + */ +export function renderTwigHtml(html, options = {}) { + return React.createElement(TwigHtmlStory, { + html: html == null ? '' : String(html), + options, + }); +} + +/** + * Convert legacy string-returning Storybook results into React elements. + * + * React stories and other non-string results pass through unchanged. + * + * @param {*} result - Story render result. + * @param {object} [options={}] - Render options for string results. + * @returns {*} React element for strings, otherwise the original result. + */ +export function renderHtmlStoryResult(result, options = {}) { + return typeof result === 'string' ? renderTwigHtml(result, options) : result; +} + +/** + * Create a React-compatible Storybook render function for a Twig template. + * + * @param {Function} template - Imported Twig module render function. + * @param {object} [options={}] - Render options. + * @returns {Function} Storybook render function. + */ +export function renderTwig(template, options = {}) { + const EmulsifyTwigStoryRender = (args = {}, storyContext = {}) => + React.createElement(TwigStory, { + template, + args, + options, + storyContext, + }); + + EmulsifyTwigStoryRender.displayName = 'EmulsifyTwigStoryRender'; + + return EmulsifyTwigStoryRender; +} diff --git a/src/storybook/render-twig.test.js b/src/storybook/render-twig.test.js new file mode 100644 index 0000000..67d4c46 --- /dev/null +++ b/src/storybook/render-twig.test.js @@ -0,0 +1,212 @@ +/** + * @file Tests for the public Twig Storybook renderer. + */ + +import React, { act } from 'react'; +import { createRoot } from 'react-dom/client'; +import { + renderHtmlStoryResult, + renderTwig, + renderTwigHtml, +} from '@emulsify/core/storybook'; +import { StoryHtmlBoundary, withLegacyStoryToString } from './render-twig.js'; + +describe('renderTwig', () => { + let container; + let root; + + beforeAll(() => { + globalThis.IS_REACT_ACT_ENVIRONMENT = true; + }); + + beforeEach(() => { + container = document.createElement('div'); + document.body.appendChild(container); + root = createRoot(container); + }); + + afterEach(() => { + act(() => { + root.unmount(); + }); + container.remove(); + delete globalThis.__EMULSIFY_ENV__; + delete window.Drupal; + delete window.drupalSettings; + }); + + it('renders Twig HTML from Storybook args', () => { + const template = ({ heading }) => `

${heading}

`; + const storyRender = renderTwig(template); + + act(() => { + root.render(storyRender({ heading: 'Example' })); + }); + + expect(container.querySelector('h2').textContent).toBe('Example'); + }); + + it('supports default-level Storybook render functions with context mapping', () => { + const template = ({ heading, renderedBy }) => + `

${heading}

`; + const storyRender = renderTwig(template, { + context: (args, storyContext) => ({ + ...args, + renderedBy: storyContext.name, + }), + }); + + act(() => { + root.render(storyRender({ heading: 'Default render' }, { name: 'CSF3' })); + }); + + expect(container.querySelector('h2').textContent).toBe('Default render'); + expect(container.querySelector('article').dataset.renderedBy).toBe('CSF3'); + }); + + it('re-renders when args change', () => { + const template = ({ heading }) => `

${heading}

`; + const storyRender = renderTwig(template); + + act(() => { + root.render(storyRender({ heading: 'First' })); + }); + act(() => { + root.render(storyRender({ heading: 'Second' })); + }); + + expect(container.querySelector('h2').textContent).toBe('Second'); + }); + + it('calls Drupal attachBehaviors only when the platform adapter enables it', async () => { + globalThis.__EMULSIFY_ENV__ = { + platformAdapter: { + storybook: { + attachDrupalBehaviors: true, + }, + }, + }; + window.Drupal = { + attachBehaviors: jest.fn(), + }; + const storyRender = renderTwig(() => '
Drupal
'); + + await act(async () => { + root.render(storyRender({})); + }); + await act(async () => { + await Promise.resolve(); + }); + + expect(window.Drupal.attachBehaviors).toHaveBeenCalledTimes(1); + expect( + window.Drupal.attachBehaviors.mock.calls[0][0].hasAttribute( + 'data-emulsify-twig-story', + ), + ).toBe(true); + }); + + it('does not create or require Drupal globals for generic platforms', () => { + globalThis.__EMULSIFY_ENV__ = { + platformAdapter: { + storybook: { + attachDrupalBehaviors: false, + }, + }, + }; + const storyRender = renderTwig(() => '
Generic
'); + + act(() => { + root.render(storyRender({})); + }); + + expect(window.Drupal).toBeUndefined(); + expect(container.textContent).toBe('Generic'); + }); + + it('renders legacy Twig HTML strings through the shared wrapper', () => { + act(() => { + root.render(renderTwigHtml('

Legacy Twig

')); + }); + + expect(container.querySelector('h2').textContent).toBe('Legacy Twig'); + expect( + container + .querySelector('[data-emulsify-twig-story]') + .hasAttribute('data-emulsify-twig-story'), + ).toBe(true); + }); + + it('converts string story results while preserving React story results', () => { + const ReactResult = React.createElement( + 'button', + { type: 'button' }, + 'React story', + ); + + act(() => { + root.render(renderHtmlStoryResult('

Legacy string

')); + }); + + expect(container.querySelector('p').textContent).toBe('Legacy string'); + expect(renderHtmlStoryResult(ReactResult)).toBe(ReactResult); + }); + + it('converts legacy HTML text rendered through a React story element', () => { + const LegacyStringStory = () => + '

Legacy React text

'; + + act(() => { + root.render( + React.createElement( + StoryHtmlBoundary, + {}, + React.createElement(LegacyStringStory), + ), + ); + }); + + expect(container.querySelector('h2').textContent).toBe('Legacy React text'); + expect(container.textContent).toBe('Legacy React text'); + }); + + it('preserves HTML for legacy decorators that stringify story results', () => { + const storyElement = withLegacyStoryToString( + React.createElement('div', null, 'React wrapper'), + () => '

Stringified Twig

', + ); + + act(() => { + root.render(renderHtmlStoryResult(`${storyElement}`)); + }); + + expect(container.querySelector('p').textContent).toBe('Stringified Twig'); + }); + + it('keeps legacy string-compatible story elements renderable by React', () => { + const LegacyStringStory = () => 'Renderable clone'; + const storyElement = withLegacyStoryToString( + React.createElement(LegacyStringStory), + () => 'Renderable clone', + ); + + act(() => { + root.render(React.createElement(StoryHtmlBoundary, {}, storyElement)); + }); + + expect(container.querySelector('strong').textContent).toBe( + 'Renderable clone', + ); + }); + + it('does not interfere with normal React story rendering', () => { + const ReactStory = ({ label }) => + React.createElement('button', { type: 'button' }, label); + + act(() => { + root.render(React.createElement(ReactStory, { label: 'React story' })); + }); + + expect(container.querySelector('button').textContent).toBe('React story'); + }); +}); diff --git a/src/storybook/twig/include.js b/src/storybook/twig/include.js new file mode 100644 index 0000000..c11c615 --- /dev/null +++ b/src/storybook/twig/include.js @@ -0,0 +1,121 @@ +/** + * @file Twig include() runtime helper for Storybook-rendered templates. + */ + +import resolveTemplate from './resolver.js'; + +/** + * Normalize optional include arguments into one options object. + * + * @param {Object} variables - Explicit include variables. + * @param {boolean|Object} withContext - Twig with-context flag or options. + * @param {boolean} ignoreMissing - Twig ignore-missing flag. + * @returns {{variables: Object, withContext: boolean, ignoreMissing: boolean}} + * Normalized include arguments. + */ +function normalizeIncludeOptions( + variables = {}, + withContext = false, + ignoreMissing = false, +) { + const normalizedVariables = + variables && typeof variables === 'object' && !Array.isArray(variables) + ? { ...variables } + : {}; + + if (typeof normalizedVariables.with_context !== 'undefined') { + withContext = normalizedVariables.with_context; + delete normalizedVariables.with_context; + } + + if (typeof normalizedVariables.ignore_missing !== 'undefined') { + ignoreMissing = normalizedVariables.ignore_missing; + delete normalizedVariables.ignore_missing; + } + + if (withContext && typeof withContext === 'object') { + const optionsObject = withContext; + + if (typeof optionsObject.with_context !== 'undefined') { + withContext = optionsObject.with_context; + } + if (typeof optionsObject.ignore_missing !== 'undefined') { + ignoreMissing = optionsObject.ignore_missing; + } + } + + return { + variables: normalizedVariables, + withContext: Boolean(withContext), + ignoreMissing: Boolean(ignoreMissing), + }; +} + +/** + * Find the first resolvable include target. + * + * @param {string|string[]} templateName - Template name or ordered candidates. + * @param {Function} resolver - Template resolver. + * @returns {Function|undefined} Resolved template render function. + */ +function resolveIncludeTarget(templateName, resolver) { + const names = Array.isArray(templateName) ? templateName : [templateName]; + + for (const name of names) { + const template = resolver(name); + if (template) { + return template; + } + } + + return undefined; +} + +/** + * Create a Twig.js `include()` function for Storybook rendering. + * + * @param {Function} resolver - Template resolver. + * @returns {Function} Twig.js function implementation. + */ +export function createTwigIncludeFunction(resolver = resolveTemplate) { + return function include(templateName, variables, withContext, ignoreMissing) { + const options = normalizeIncludeOptions( + variables, + withContext, + ignoreMissing, + ); + + try { + const templateFn = resolveIncludeTarget(templateName, resolver); + if (!templateFn) { + if (!options.ignoreMissing) { + console.error(`Twig include() could not resolve: ${templateName}`); + } + return ''; + } + + const finalContext = options.withContext + ? { ...(this?.context || {}), ...options.variables } + : options.variables; + + return templateFn(finalContext); + } catch (error) { + if (!options.ignoreMissing) { + console.error(`Twig include() failed for: ${templateName}`, error); + } + return ''; + } + }; +} + +/** + * Twig `include()` runtime helper. + * + * @param {Object} Twig - Twig.js module. + * @returns {undefined} + */ +function twigInclude(Twig) { + Twig.extendFunction('include', createTwigIncludeFunction()); +} + +export default twigInclude; diff --git a/src/storybook/twig/include.test.js b/src/storybook/twig/include.test.js new file mode 100644 index 0000000..5e74f03 --- /dev/null +++ b/src/storybook/twig/include.test.js @@ -0,0 +1,84 @@ +/** + * @file Tests for the Storybook Twig include() runtime helper. + */ + +import { createTwigIncludeFunction } from './include.js'; + +describe('Twig include() Storybook helper', () => { + let consoleError; + + beforeEach(() => { + consoleError = jest.spyOn(console, 'error').mockImplementation(() => {}); + }); + + afterEach(() => { + consoleError.mockRestore(); + }); + + it('renders the resolved template with explicit variables', () => { + const template = jest.fn(({ text }) => `${text}`); + const include = createTwigIncludeFunction(() => template); + + expect(include('@components/button', { text: 'Read more' })).toBe( + 'Read more', + ); + expect(template).toHaveBeenCalledWith({ text: 'Read more' }); + }); + + it('can merge the current Twig context when with_context is enabled', () => { + const template = jest.fn( + ({ theme, text }) => `${text}`, + ); + const include = createTwigIncludeFunction(() => template); + + expect( + include.call( + { context: { theme: 'dark' } }, + '@components/button', + { text: 'Read more' }, + true, + ), + ).toBe('Read more'); + expect(template).toHaveBeenCalledWith({ + theme: 'dark', + text: 'Read more', + }); + }); + + it('supports options passed through the variables object', () => { + const template = jest.fn(({ theme, text }) => `${theme}:${text}`); + const include = createTwigIncludeFunction(() => template); + + expect( + include.call({ context: { theme: 'light' } }, '@components/button', { + text: 'Read more', + with_context: true, + }), + ).toBe('light:Read more'); + expect(template).toHaveBeenCalledWith({ + theme: 'light', + text: 'Read more', + }); + }); + + it('uses the first resolvable template from an ordered candidate list', () => { + const template = jest.fn(() => 'Fallback'); + const resolver = jest.fn((name) => + name === '@components/fallback' ? template : undefined, + ); + const include = createTwigIncludeFunction(resolver); + + expect(include(['@components/missing', '@components/fallback'], {})).toBe( + 'Fallback', + ); + expect(resolver).toHaveBeenCalledWith('@components/missing'); + expect(resolver).toHaveBeenCalledWith('@components/fallback'); + }); + + it('returns an empty string for ignored missing templates', () => { + const include = createTwigIncludeFunction(() => undefined); + + expect(include('@components/missing', { ignore_missing: true })).toBe(''); + expect(consoleError).not.toHaveBeenCalled(); + }); +}); diff --git a/src/storybook/twig/resolver.js b/src/storybook/twig/resolver.js new file mode 100644 index 0000000..02d4505 --- /dev/null +++ b/src/storybook/twig/resolver.js @@ -0,0 +1,331 @@ +/** + * @file Runtime Twig template resolver used by Storybook Twig helpers. + */ + +import { unique } from '../../extensions/shared/lists.js'; +import { + modules as twigModules, + sources as twigSources, +} from 'virtual:emulsify-twig-globs'; + +const ENV = (typeof __EMULSIFY_ENV__ !== 'undefined' && __EMULSIFY_ENV__) || {}; + +const normalizeGlobPath = (filePath) => filePath.replace(/\\/g, '/'); + +/** + * Convert an absolute project path to a Vite root-relative key. + * + * @param {string} absolutePath - Absolute file or directory path. + * @param {object} env - Normalized Emulsify environment. + * @returns {string} Root-relative path with a leading slash. + */ +export function toRootRelativePath(absolutePath, env = ENV) { + if (!absolutePath) return ''; + + const normalizedPath = normalizeGlobPath(absolutePath); + const projectDir = normalizeGlobPath(env?.projectDir || ''); + + if (projectDir && normalizedPath.startsWith(projectDir)) { + const relativePath = normalizedPath.slice(projectDir.length); + return relativePath.startsWith('/') ? relativePath : `/${relativePath}`; + } + + return normalizedPath.startsWith('/') ? normalizedPath : `/${normalizedPath}`; +} + +/** + * Normalize a Twig root declaration into resolver metadata. + * + * @param {{name?: string, directory?: string}|string} root - Root declaration. + * @param {object} env - Normalized Emulsify environment. + * @returns {{name: string|undefined, directory: string, rootRel: string}|null} + */ +function normalizeRootRecord(root, env) { + const directory = typeof root === 'string' ? root : root?.directory; + if (!directory) return null; + + return { + name: typeof root === 'string' ? undefined : root.name, + directory, + rootRel: toRootRelativePath(directory, env), + }; +} + +/** + * Build Twig roots from the normalized project structure. + * + * @param {object} [env=ENV] - Normalized Emulsify environment. + * @returns {{name: string|undefined, directory: string, rootRel: string}[]} + * Twig roots in resolution order. + */ +export function buildTwigRootRecords(env = ENV) { + const structure = env?.projectStructure || {}; + const namespaceRoots = + structure.namespaceRoots && typeof structure.namespaceRoots === 'object' + ? structure.namespaceRoots + : env?.namespaceRoots && typeof env.namespaceRoots === 'object' + ? env.namespaceRoots + : {}; + const namedRoots = [ + ...(Array.isArray(structure.componentRootRecords) + ? structure.componentRootRecords + : []), + ...(Array.isArray(env?.structureImplementations) + ? env.structureImplementations + : []), + ...Object.entries(namespaceRoots).map(([name, directory]) => ({ + name, + directory, + })), + ]; + const unnamedRoots = [ + ...(Array.isArray(structure.twigRoots) ? structure.twigRoots : []), + ...(Array.isArray(env?.componentRoots) ? env.componentRoots : []), + ...(env?.srcDir ? [env.srcDir] : []), + ]; + const fallbackRoots = env?.projectDir + ? [ + `${env.projectDir}/src`, + `${env.projectDir}/src/components`, + `${env.projectDir}/components`, + ] + : ['/src', '/src/components', '/components']; + const records = [...namedRoots, ...unnamedRoots, ...fallbackRoots] + .map((root) => normalizeRootRecord(root, env)) + .filter(Boolean); + + return unique( + records.map((record) => `${record.name || ''}|${record.rootRel}`), + ) + .map((key) => + records.find( + (record) => `${record.name || ''}|${record.rootRel}` === key, + ), + ) + .filter(Boolean); +} + +/** + * Remove a Twig file extension from a reference. + * + * @param {string} value - Template reference. + * @returns {string} Reference without `.twig` or `.html.twig`. + */ +function removeTwigExtension(value) { + return value.replace(/\.html\.twig$/i, '').replace(/\.twig$/i, ''); +} + +/** + * Build candidate keys below one root for a template reference. + * + * @param {string} rootRel - Root-relative Twig root. + * @param {string} reference - Template reference relative to the root. + * @returns {string[]} Candidate Vite glob keys. + */ +export function candidateKeysForRoot(rootRel, reference) { + const cleanReference = reference.replace(/^[./]+/, '').replace(/^\/+/, ''); + const hasHtmlExtension = /\.html\.twig$/i.test(cleanReference); + const hasTwigExtension = /\.twig$/i.test(cleanReference); + const withoutExtension = removeTwigExtension(cleanReference); + const stem = withoutExtension.split('/').pop(); + const explicitCandidates = hasHtmlExtension + ? [ + `${rootRel}/${withoutExtension}.html.twig`, + `${rootRel}/${withoutExtension}.twig`, + ] + : [ + `${rootRel}/${withoutExtension}.twig`, + `${rootRel}/${withoutExtension}.html.twig`, + ]; + const shorthandCandidates = [ + `${rootRel}/${withoutExtension}/${stem}.twig`, + `${rootRel}/${withoutExtension}/${stem}.html.twig`, + ...explicitCandidates, + ]; + + return unique( + (hasTwigExtension || withoutExtension.includes('/') + ? explicitCandidates + : shorthandCandidates + ).map((key) => key.replace(/\/{2,}/g, '/')), + ); +} + +/** + * Find root records for a namespace. + * + * @param {string} namespace - Namespace name. + * @param {{name?: string}[]} roots - Twig root records. + * @returns {object[]} Matching root records. + */ +function rootsForNamespace(namespace, roots) { + return roots.filter((root) => root.name === namespace); +} + +/** + * Parse a Twig template reference into namespace and relative path parts. + * + * @param {string} name - Template reference. + * @returns {{namespace?: string, path: string, shorthand?: boolean}|null} + */ +function parseTemplateReference(name) { + if (typeof name !== 'string' || !name.trim()) return null; + + const cleanName = name.trim(); + const colonMatch = cleanName.match(/^([^:/.]+):(.+)$/); + if (colonMatch) { + return { + namespace: colonMatch[1], + path: colonMatch[2], + }; + } + + const atMatch = cleanName.match(/^@([^/]+)\/(.+)$/); + if (atMatch) { + return { + namespace: atMatch[1], + path: atMatch[2], + }; + } + + if (cleanName.startsWith('@')) { + return { + path: cleanName.slice(1), + shorthand: true, + }; + } + + const slashMatch = cleanName.match(/^([^/]+)\/(.+)$/); + if (slashMatch) { + return { + namespace: slashMatch[1], + path: slashMatch[2], + }; + } + + return { + path: cleanName, + shorthand: true, + }; +} + +/** + * Build candidate Vite glob keys for a Twig reference. + * + * @param {string} name - Template reference. + * @param {object} env - Normalized Emulsify environment. + * @returns {string[]} Candidate Vite glob keys. + */ +export function candidateKeysForReference(name, env = ENV) { + const roots = buildTwigRootRecords(env); + const parsed = parseTemplateReference(name); + if (!parsed) return []; + + const projectNamespace = env?.machineName; + const namespaceRoots = + parsed.namespace && parsed.namespace !== projectNamespace + ? rootsForNamespace(parsed.namespace, roots) + : []; + const searchRoots = namespaceRoots.length ? namespaceRoots : roots; + const searchPaths = unique([ + parsed.path, + ...(parsed.namespace && !namespaceRoots.length + ? [`${parsed.namespace}/${parsed.path}`] + : []), + ]); + + return unique( + searchRoots.flatMap((root) => + searchPaths.flatMap((part) => candidateKeysForRoot(root.rootRel, part)), + ), + ); +} + +/** + * Resolve a value from a Vite glob map. + * + * @param {Record} map - Vite glob map. + * @param {string[]} candidates - Candidate map keys. + * @returns {*} Resolved map value. + */ +function resolveFromMap(map, candidates) { + for (const key of candidates) { + // Vite glob map keys are generated from static Storybook patterns. + // eslint-disable-next-line security/detect-object-injection + const value = map[key]; + if (value) { + return value.default ?? value; + } + } + + return undefined; +} + +/** + * Create a Twig resolver bound to a normalized environment and Vite maps. + * + * @param {{ + * env?: object, + * modules?: Record, + * sources?: Record + * }} options - Resolver inputs. + * @returns {{resolveTemplate: Function, resolveTemplateSource: Function, candidateKeysForReference: Function}} + * Resolver functions. + */ +export function createTwigResolver({ + env = ENV, + modules = twigModules, + sources = twigSources, +} = {}) { + return { + candidateKeysForReference: (name) => candidateKeysForReference(name, env), + resolveTemplate(name) { + // Direct lookups support callers that already resolved a Vite glob key. + // eslint-disable-next-line security/detect-object-injection + const direct = modules[name]; + if (direct) { + return direct.default ?? direct; + } + + const candidates = candidateKeysForReference(name, env); + const template = resolveFromMap(modules, candidates); + if (template) { + return template; + } + + return undefined; + }, + resolveTemplateSource(name) { + // Direct lookups support callers that already resolved a Vite glob key. + // eslint-disable-next-line security/detect-object-injection + const direct = sources[name]; + if (typeof direct === 'string') { + return direct; + } + + return resolveFromMap(sources, candidateKeysForReference(name, env)); + }, + }; +} + +const defaultResolver = createTwigResolver(); + +/** + * Resolve a template identifier to a compiled Twig render function. + * + * @param {string} name - Template identifier. + * @returns {Function|undefined} Render function when available. + */ +export default function resolveTemplate(name) { + return defaultResolver.resolveTemplate(name); +} + +/** + * Resolve a template identifier to raw Twig source. + * + * @param {string} name - Template identifier. + * @returns {string|undefined} Raw Twig source when available. + */ +export function resolveTemplateSource(name) { + return defaultResolver.resolveTemplateSource(name); +} diff --git a/src/storybook/twig/resolver.test.js b/src/storybook/twig/resolver.test.js new file mode 100644 index 0000000..254275a --- /dev/null +++ b/src/storybook/twig/resolver.test.js @@ -0,0 +1,153 @@ +/** + * @file Tests for the Storybook Twig template resolver. + */ + +import { + buildTwigRootRecords, + candidateKeysForReference, + candidateKeysForRoot, + createTwigResolver, +} from './resolver.js'; + +const projectDir = '/project'; + +const createEnv = () => ({ + projectDir, + machineName: 'whisk', + projectStructure: { + componentRootRecords: [ + { name: 'components', directory: `${projectDir}/src/components` }, + ], + twigRoots: [`${projectDir}/src/components`, `${projectDir}/src/layout`], + namespaceRoots: { + components: `${projectDir}/src/components`, + layout: `${projectDir}/src/layout`, + }, + }, +}); + +describe('Storybook Twig resolver', () => { + it('builds roots from the normalized project structure', () => { + expect(buildTwigRootRecords(createEnv())).toEqual([ + { + name: 'components', + directory: '/project/src/components', + rootRel: '/src/components', + }, + { + name: 'layout', + directory: '/project/src/layout', + rootRel: '/src/layout', + }, + { + name: undefined, + directory: '/project/src/components', + rootRel: '/src/components', + }, + { + name: undefined, + directory: '/project/src/layout', + rootRel: '/src/layout', + }, + { + name: undefined, + directory: '/project/src', + rootRel: '/src', + }, + { + name: undefined, + directory: '/project/components', + rootRel: '/components', + }, + ]); + }); + + it('builds candidate keys for explicit and shorthand component references', () => { + expect(candidateKeysForRoot('/src/components', 'button')).toEqual([ + '/src/components/button/button.twig', + '/src/components/button/button.html.twig', + '/src/components/button.twig', + '/src/components/button.html.twig', + ]); + expect( + candidateKeysForRoot('/src/components', 'button/button.html.twig'), + ).toEqual([ + '/src/components/button/button.html.twig', + '/src/components/button/button.twig', + ]); + + expect( + candidateKeysForReference('@components/button/button.twig', createEnv()), + ).toContain('/src/components/button/button.twig'); + expect( + candidateKeysForReference('components:button', createEnv()), + ).toContain('/src/components/button/button.twig'); + expect(candidateKeysForReference('whisk:button', createEnv())).toContain( + '/src/components/button/button.twig', + ); + }); + + it('resolves compiled Twig modules and raw Twig source', () => { + const buttonTemplate = jest.fn(() => ''); + const resolver = createTwigResolver({ + env: createEnv(), + modules: { + '/src/components/button/button.twig': { default: buttonTemplate }, + }, + sources: { + '/src/components/button/button.twig': '', + }, + }); + + expect(resolver.resolveTemplate('@components/button/button.twig')).toBe( + buttonTemplate, + ); + expect(resolver.resolveTemplate('components:button')).toBe(buttonTemplate); + expect(resolver.resolveTemplate('missing')).toBeUndefined(); + expect( + resolver.resolveTemplateSource('@components/button/button.twig'), + ).toBe(''); + }); + + it('resolves named variant structure roots as Twig namespaces', () => { + const env = { + projectDir, + projectStructure: { + componentRootRecords: [ + { name: 'components', directory: `${projectDir}/src/components` }, + { name: 'foundation', directory: `${projectDir}/src/foundation` }, + { name: 'layout', directory: `${projectDir}/src/layout` }, + { name: 'tokens', directory: `${projectDir}/src/tokens` }, + ], + namespaceRoots: { + components: `${projectDir}/src/components`, + foundation: `${projectDir}/src/foundation`, + layout: `${projectDir}/src/layout`, + tokens: `${projectDir}/src/tokens`, + }, + }, + }; + const paletteTemplate = jest.fn(() => '
Palette
'); + const resolver = createTwigResolver({ + env, + modules: { + '/src/foundation/colors/palette.twig': { + default: paletteTemplate, + }, + }, + sources: { + '/src/tokens/color/color.twig': '{{ color }}', + }, + }); + + expect(resolver.resolveTemplate('@foundation/colors/palette.twig')).toBe( + paletteTemplate, + ); + expect( + candidateKeysForReference('@tokens/color/color.twig', env), + ).toContain('/src/tokens/color/color.twig'); + expect(resolver.resolveTemplateSource('@tokens/color/color.twig')).toBe( + '{{ color }}', + ); + }); +}); diff --git a/src/storybook/twig/setup.js b/src/storybook/twig/setup.js new file mode 100644 index 0000000..71cf74a --- /dev/null +++ b/src/storybook/twig/setup.js @@ -0,0 +1,39 @@ +/** + * @file Twig runtime setup for Emulsify's Storybook integration. + */ + +import { registerTwigExtensions } from '../../extensions/twig/index.js'; +import twigInclude from './include.js'; +import twigSource from './source.js'; + +/** + * Configures and extends a standard Twig object for Storybook. + * + * Emulsify's Twig helpers are platform-agnostic. Platform adapters can pass + * optional Twig extension functions when a project needs CMS-specific behavior. + * + * @param {Object} twig - Twig object that should be configured and extended. + * @param {{ extensions?: Function[] }} [options={}] - Optional platform extensions. + * @returns {Object} Configured Twig object. + */ +export function setupTwig(twig, options = {}) { + const extensions = Array.isArray(options.extensions) + ? options.extensions + : []; + + twig.cache(); + registerTwigExtensions(twig); + twigInclude(twig); + twigSource(twig); + + for (const extension of extensions) { + if (typeof extension === 'function') { + extension(twig); + } + } + + return twig; +} + +export { default as twigInclude } from './include.js'; +export { default as twigSource } from './source.js'; diff --git a/src/storybook/twig/setup.test.js b/src/storybook/twig/setup.test.js new file mode 100644 index 0000000..aaa99e4 --- /dev/null +++ b/src/storybook/twig/setup.test.js @@ -0,0 +1,39 @@ +/** + * @file Tests for Storybook Twig runtime setup. + */ + +import { setupTwig } from './setup.js'; + +describe('Storybook Twig setup', () => { + it('registers Emulsify Twig helpers, include(), source(), and optional platform extensions', () => { + const functionNames = []; + const tagTypes = []; + const platformExtension = jest.fn(); + const Twig = { + cache: jest.fn(), + extend: jest.fn((callback) => callback({})), + extendFunction: jest.fn((name) => { + functionNames.push(name); + }), + extendTag: jest.fn((definition) => { + tagTypes.push(definition.type); + }), + }; + + expect(setupTwig(Twig, { extensions: [platformExtension] })).toBe(Twig); + + expect(Twig.cache).toHaveBeenCalledTimes(1); + expect(functionNames).toEqual( + expect.arrayContaining(['add_attributes', 'bem', 'include', 'source']), + ); + expect(tagTypes).toEqual( + expect.arrayContaining([ + 'emulsify_switch', + 'emulsify_case', + 'emulsify_default', + 'emulsify_endswitch', + ]), + ); + expect(platformExtension).toHaveBeenCalledWith(Twig); + }); +}); diff --git a/src/storybook/twig/source.js b/src/storybook/twig/source.js new file mode 100644 index 0000000..7a3a9d6 --- /dev/null +++ b/src/storybook/twig/source.js @@ -0,0 +1,130 @@ +/** + * @file Twig source() runtime helper for Storybook-rendered templates. + */ + +import { resolveTemplateSource } from './resolver.js'; + +const ENV = (typeof __EMULSIFY_ENV__ !== 'undefined' && __EMULSIFY_ENV__) || {}; + +// GitHub Pages serves static assets from a repository-prefixed base path. +const PUBLIC_ASSET_BASE = + typeof window !== 'undefined' && + window.location && + window.location.hostname && + window.location.hostname.endsWith('github.io') + ? `/${ENV.machineName || ''}/assets/` + : '/assets/'; + +// Text assets can be safely inlined; binary assets should remain URL-based. +const INLINE_ASSET_EXTS = new Set([ + 'svg', + 'html', + 'twig', + 'css', + 'js', + 'json', + 'txt', + 'md', +]); +const IMAGE_ASSET_EXTS = new Set(['png', 'jpg', 'jpeg', 'gif', 'webp', 'avif']); + +/** + * Normalize an `@assets` reference to a public asset path. + * + * @param {string} assetPath - Twig asset reference. + * @returns {string} Asset path below the public asset base. + */ +function normalizeAssetPath(assetPath) { + return assetPath.replace(/^@assets\//, '').replace(/^assets\//, ''); +} + +/** + * Read a text asset from Storybook's static server. + * + * @param {string} relPath - Public asset path below `/assets`. + * @returns {string|undefined} Fetched text when available. + */ +function fetchTextAsset(relPath) { + try { + const xhr = new XMLHttpRequest(); + xhr.open('GET', `${PUBLIC_ASSET_BASE}${relPath}`, false); + xhr.send(null); + if (xhr.status >= 200 && xhr.status < 300) { + return xhr.responseText; + } + + console.error(`source(): ${xhr.status} while fetching ${relPath}`); + } catch (error) { + console.error(`source(): failed to fetch ${relPath}`, error); + } + + return undefined; +} + +/** + * Resolve an `@assets` reference for Storybook. + * + * @param {string} assetPath - Twig asset reference. + * @returns {string} Raw text, image markup, or URL. + */ +export function resolveAssetSource(assetPath) { + const relPath = normalizeAssetPath(assetPath); + const extension = relPath.split('.').pop().toLowerCase(); + + if (INLINE_ASSET_EXTS.has(extension)) { + const text = fetchTextAsset(relPath); + if (typeof text === 'string') { + return text; + } + } + + if (IMAGE_ASSET_EXTS.has(extension)) { + return ``; + } + + return `${PUBLIC_ASSET_BASE}${relPath}`; +} + +/** + * Create a Twig.js `source()` function for Storybook rendering. + * + * @param {Function} templateSourceResolver - Twig template source resolver. + * @returns {Function} Twig.js function implementation. + */ +export function createTwigSourceFunction( + templateSourceResolver = resolveTemplateSource, +) { + return function source(templateName, ignoreMissing = false) { + if (typeof templateName !== 'string') return ''; + + const templateSource = templateSourceResolver(templateName); + if (typeof templateSource === 'string') { + return templateSource; + } + + if ( + templateName.startsWith('@assets/') || + templateName.startsWith('assets/') + ) { + return resolveAssetSource(templateName); + } + + if (!ignoreMissing) { + console.error(`source(): cannot resolve ${templateName}`); + } + + return ''; + }; +} + +/** + * Twig `source()` runtime helper. + * + * @param {Object} Twig - Twig.js module. + * @returns {undefined} + */ +function twigSource(Twig) { + Twig.extendFunction('source', createTwigSourceFunction()); +} + +export default twigSource; diff --git a/src/storybook/twig/source.test.js b/src/storybook/twig/source.test.js new file mode 100644 index 0000000..f5dfa79 --- /dev/null +++ b/src/storybook/twig/source.test.js @@ -0,0 +1,48 @@ +/** + * @file Tests for the Storybook Twig source() runtime helper. + */ + +import { createTwigSourceFunction, resolveAssetSource } from './source.js'; + +describe('Twig source() Storybook helper', () => { + let consoleError; + + beforeEach(() => { + consoleError = jest.spyOn(console, 'error').mockImplementation(() => {}); + }); + + afterEach(() => { + consoleError.mockRestore(); + }); + + it('returns raw Twig source from the template resolver', () => { + const source = createTwigSourceFunction((name) => + name === '@components/button/button.twig' + ? '' + : undefined, + ); + + expect(source('@components/button/button.twig')).toBe( + '', + ); + }); + + it('resolves raster assets to public Storybook image markup', () => { + expect(resolveAssetSource('@assets/icons/arrow.png')).toBe( + '', + ); + }); + + it('returns a public URL for non-inline, non-image assets', () => { + expect(resolveAssetSource('@assets/fonts/icon.woff2')).toBe( + '/assets/fonts/icon.woff2', + ); + }); + + it('returns an empty string for ignored missing template source', () => { + const source = createTwigSourceFunction(() => undefined); + + expect(source('@components/missing.twig', true)).toBe(''); + expect(consoleError).not.toHaveBeenCalled(); + }); +});