diff --git a/package-lock.json b/package-lock.json
index 617865eb..daf386d9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,7 +15,7 @@
"@web/test-runner": "0.14.0",
"@web/test-runner-commands": "0.6.4",
"chai": "4.3.6",
- "eslint": "8.22.0",
+ "eslint": "^8.22.0",
"eslint-config-airbnb-base": "15.0.0",
"eslint-plugin-import": "2.26.0",
"puppeteer": "^21.2.1",
@@ -2490,6 +2490,7 @@
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.22.0.tgz",
"integrity": "sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@eslint/eslintrc": "^1.3.0",
"@humanwhocodes/config-array": "^0.10.4",
diff --git a/package.json b/package.json
index c2cf80b1..1cf94a39 100644
--- a/package.json
+++ b/package.json
@@ -28,13 +28,13 @@
"@web/test-runner": "0.14.0",
"@web/test-runner-commands": "0.6.4",
"chai": "4.3.6",
- "eslint": "8.22.0",
+ "eslint": "^8.22.0",
"eslint-config-airbnb-base": "15.0.0",
"eslint-plugin-import": "2.26.0",
+ "puppeteer": "^21.2.1",
"sinon": "14.0.0",
"stylelint": "14.10.0",
"stylelint-config-prettier": "9.0.3",
- "stylelint-config-standard": "25.0.0",
- "puppeteer": "^21.2.1"
+ "stylelint-config-standard": "25.0.0"
}
}
diff --git a/plugins/experimentation/.eslintignore b/plugins/experimentation/.eslintignore
deleted file mode 100644
index 0a87cad0..00000000
--- a/plugins/experimentation/.eslintignore
+++ /dev/null
@@ -1 +0,0 @@
-src/ued.js
\ No newline at end of file
diff --git a/plugins/experimentation/.github/workflows/release.yaml b/plugins/experimentation/.github/workflows/release.yaml
new file mode 100644
index 00000000..a72f6cd6
--- /dev/null
+++ b/plugins/experimentation/.github/workflows/release.yaml
@@ -0,0 +1,36 @@
+name: Release
+on:
+ push:
+ branches:
+ - main
+
+permissions:
+ contents: read
+
+jobs:
+ release:
+ name: Release
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ issues: write
+ pull-requests: write
+ id-token: write
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - name: Setup Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: "lts/*"
+ - name: Install dependencies
+ run: npm ci
+ - name: Verify the integrity of provenance attestations and registry signatures for installed dependencies
+ run: npm audit signatures
+ - name: Release
+ env:
+ # Token taken from: https://app.codecov.io/github/adobe/aem-experimentation/settings
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: npx semantic-release
\ No newline at end of file
diff --git a/plugins/experimentation/.github/workflows/run-tests.yaml b/plugins/experimentation/.github/workflows/run-tests.yaml
new file mode 100644
index 00000000..5eb55c09
--- /dev/null
+++ b/plugins/experimentation/.github/workflows/run-tests.yaml
@@ -0,0 +1,28 @@
+name: Linting
+
+on: [pull_request]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ container:
+ image: mcr.microsoft.com/playwright:v1.44.1-jammy
+ steps:
+ - uses: actions/checkout@v3
+ - name: Use Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: '20'
+ - run: npm ci
+ - run: npm run lint
+ env:
+ CI: true
+ - run: npm run test
+ env:
+ CI: true
+ - name: Codecov
+ uses: codecov/codecov-action@v4
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ slug: adobe/aem-experimentation
+ files: ./coverage/codecov.json
diff --git a/plugins/experimentation/.gitignore b/plugins/experimentation/.gitignore
new file mode 100644
index 00000000..c059a6ff
--- /dev/null
+++ b/plugins/experimentation/.gitignore
@@ -0,0 +1,3 @@
+coverage/
+playwright-report/
+test-results/
\ No newline at end of file
diff --git a/plugins/experimentation/.releaserc b/plugins/experimentation/.releaserc
new file mode 100644
index 00000000..904333e4
--- /dev/null
+++ b/plugins/experimentation/.releaserc
@@ -0,0 +1,13 @@
+{
+ "branches": ["main"],
+ "plugins": [
+ "@semantic-release/commit-analyzer",
+ "@semantic-release/release-notes-generator",
+ "@semantic-release/changelog",
+ "@semantic-release/npm",
+ ["@semantic-release/git", {
+ "assets": ["CHANGELOG.md", "package.json"],
+ "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
+ }]
+ ]
+}
\ No newline at end of file
diff --git a/plugins/experimentation/CHANGELOG.md b/plugins/experimentation/CHANGELOG.md
new file mode 100644
index 00000000..27eb2494
--- /dev/null
+++ b/plugins/experimentation/CHANGELOG.md
@@ -0,0 +1,6 @@
+## [1.0.1](https://github.com/adobe/aem-experimentation/compare/v1.0.0...v1.0.1) (2024-05-24)
+
+
+### Bug Fixes
+
+* semantic release ([5040fa8](https://github.com/adobe/aem-experimentation/commit/5040fa88c7a01b032431967e230abaaf6d69f9d6))
diff --git a/plugins/experimentation/README.md b/plugins/experimentation/README.md
index 1a9efb14..3a997ab6 100644
--- a/plugins/experimentation/README.md
+++ b/plugins/experimentation/README.md
@@ -26,113 +26,115 @@ git subtree pull --squash --prefix plugins/experimentation git@github.com:adobe/
If you prefer using `https` links you'd replace `git@github.com:adobe/aem-experimentation.git` in the above commands by `https://github.com/adobe/aem-experimentation.git`.
-If the `subtree pull` command is failing with an error like:
-```
-fatal: can't squash-merge: 'plugins/experimentation' was never added
-```
-you can just delete the folder and re-add the plugin via the `git subtree add` command above.
-
## Project instrumentation
-:warning: The plugin requires that you have a recent RUM instrumentation from the AEM boilerplate that supports `sampleRUM.always`. If you are getting errors that `.on` cannot be called on an `undefined` object, please apply the changes from https://github.com/adobe/aem-boilerplate/pull/247/files to your `lib-franklin.js`.
-
-### On top of the plugin system
-
-The easiest way to add the plugin is if your project is set up with the plugin system extension in the boilerplate.
-You'll know you have it if `window.hlx.plugins` is defined on your page.
-
-If you don't have it, you can follow the proposal in https://github.com/adobe/aem-lib/pull/23 and https://github.com/adobe/aem-boilerplate/pull/275 and apply the changes to your `aem.js`/`lib-franklin.js` and `scripts.js`.
-
-Once you have confirmed this, you'll need to edit your `scripts.js` in your AEM project and add the following at the start of the file:
-```js
-const AUDIENCES = {
- mobile: () => window.innerWidth < 600,
- desktop: () => window.innerWidth >= 600,
- // define your custom audiences here as needed
-};
-
-window.hlx.plugins.add('experimentation', {
- condition: () => getMetadata('experiment')
- || Object.keys(getAllMetadata('campaign')).length
- || Object.keys(getAllMetadata('audience')).length,
- options: { audiences: AUDIENCES },
- url: '/plugins/experimentation/src/index.js',
-});
-```
-
### On top of a regular boilerplate project
-Typically, you'd know you don't have the plugin system if you don't see a reference to `window.hlx.plugins` in your `scripts.js`. In that case, you can still manually instrument this plugin in your project by falling back to a more manual instrumentation. To properly connect and configure the plugin for your project, you'll need to edit your `scripts.js` in your AEM project and add the following:
+Typically, you'd know you don't have the plugin system if you don't see a reference to `window.aem.plugins` or `window.hlx.plugins` in your `scripts.js`. In that case, you can still manually instrument this plugin in your project by falling back to a more manual instrumentation. To properly connect and configure the plugin for your project, you'll need to edit your `scripts.js` in your AEM project and add the following:
1. at the start of the file:
```js
- const AUDIENCES = {
- mobile: () => window.innerWidth < 600,
- desktop: () => window.innerWidth >= 600,
- // define your custom audiences here as needed
+ const experimentationConfig = {
+ prodHost: 'www.my-site.com',
+ audiences: {
+ mobile: () => window.innerWidth < 600,
+ desktop: () => window.innerWidth >= 600,
+ // define your custom audiences here as needed
+ }
};
- /**
- * Gets all the metadata elements that are in the given scope.
- * @param {String} scope The scope/prefix for the metadata
- * @returns an array of HTMLElement nodes that match the given scope
- */
- export function getAllMetadata(scope) {
- return [...document.head.querySelectorAll(`meta[property^="${scope}:"],meta[name^="${scope}-"]`)]
- .reduce((res, meta) => {
- const id = toClassName(meta.name
- ? meta.name.substring(scope.length + 1)
- : meta.getAttribute('property').split(':')[1]);
- res[id] = meta.getAttribute('content');
- return res;
- }, {});
+ let runExperimentation;
+ let showExperimentationOverlay;
+ const isExperimentationEnabled = document.head.querySelector('[name^="experiment"],[name^="campaign-"],[name^="audience-"]')
+ || [...document.querySelectorAll('.section-metadata div')].some((d) => d.textContent.match(/Experiment|Campaign|Audience/i));
+ if (isExperimentationEnabled) {
+ const {
+ loadEager: runExperimentation,
+ loadLazy: showExperimentationOverlay,
+ } = await import('../plugins/experimentation/src/index.js');
}
```
-2. if this is the first plugin you add to your project, you'll also need to add:
- ```js
- // Define an execution context
- const pluginContext = {
- getAllMetadata,
- getMetadata,
- loadCSS,
- loadScript,
- sampleRUM,
- toCamelCase,
- toClassName,
- };
- ```
-3. Early in the `loadEager` method you'll need to add:
+2. Early in the `loadEager` method you'll need to add:
```js
async function loadEager(doc) {
…
// Add below snippet early in the eager phase
- if (getMetadata('experiment')
- || Object.keys(getAllMetadata('campaign')).length
- || Object.keys(getAllMetadata('audience')).length) {
- // eslint-disable-next-line import/no-relative-packages
- const { loadEager: runEager } = await import('../plugins/experimentation/src/index.js');
- await runEager(document, { audiences: AUDIENCES }, pluginContext);
+ if (runExperimentation) {
+ await runExperimentation(document, experimentationConfig);
}
…
}
```
This needs to be done as early as possible since this will be blocking the eager phase and impacting your LCP, so we want this to execute as soon as possible.
-4. Finally at the end of the `loadLazy` method you'll have to add:
+3. Finally at the end of the `loadLazy` method you'll have to add:
```js
async function loadLazy(doc) {
…
// Add below snippet at the end of the lazy phase
- if ((getMetadata('experiment')
- || Object.keys(getAllMetadata('campaign')).length
- || Object.keys(getAllMetadata('audience')).length)) {
- // eslint-disable-next-line import/no-relative-packages
- const { loadLazy: runLazy } = await import('../plugins/experimentation/src/index.js');
- await runLazy(document, { audiences: AUDIENCES }, pluginContext);
+ if (showExperimentationOverlay) {
+ await showExperimentationOverlay(document, experimentationConfig);
}
}
```
This is mostly used for the authoring overlay, and as such isn't essential to the page rendering, so having it at the end of the lazy phase is good enough.
+### On top of the plugin system
+
+The easiest way to add the plugin is if your project is set up with the plugin system extension in the boilerplate.
+You'll know you have it if either `window.aem.plugins` or `window.hlx.plugins` is defined on your page.
+
+If you don't have it, you can follow the proposal in https://github.com/adobe/aem-lib/pull/23 and https://github.com/adobe/aem-boilerplate/pull/275 and apply the changes to your `aem.js`/`lib-franklin.js` and `scripts.js`.
+
+Once you have confirmed this, you'll need to edit your `scripts.js` in your AEM project and add the following at the start of the file:
+```js
+const experimentationConfig = {
+ prodHost: 'www.my-site.com',
+ audiences: {
+ mobile: () => window.innerWidth < 600,
+ desktop: () => window.innerWidth >= 600,
+ // define your custom audiences here as needed
+ }
+};
+
+window.aem.plugins.add('experimentation', { // use window.hlx instead of your project has this
+ condition: () =>
+ // page level metadata
+ document.head.querySelector('[name^="experiment"],[name^="campaign-"],[name^="audience-"]')
+ // decorated section metadata
+ || document.querySelector('.section[class*=experiment],.section[class*=audience],.section[class*=campaign]')
+ // undecorated section metadata
+ || [...document.querySelectorAll('.section-metadata div')].some((d) => d.textContent.match(/Experiment|Campaign|Audience/i)),
+ options: experimentationConfig,
+ url: '/plugins/experimentation/src/index.js',
+});
+```
+
+### Increasing sampling rate for low traffic pages
+
+When running experiments during short periods (i.e. a few days or 2 weeks) or on low-traffic pages (<100K page views a month), it is unlikely that you'll reach statistical significance on your tests with the default RUM sampling. For those use cases, we recommend adjusting the sampling rate for the pages in question to 1 out of 10 instead of the default 1 out of 100 visits.
+
+Edit your html `
` and set configure the RUM sampling like:
+```html
+
+...
+
+
+
+
+```
+
+Then double-check your `aem.js` file around line 20 and look for:
+```js
+const weight = new URLSearchParams(window.location.search).get('rum') === 'on' ? 1 : defaultSamplingRate;
+```
+
+If this is not present, please apply the following changes to the file: https://github.com/adobe/helix-rum-js/pull/159/files#diff-bfe9874d239014961b1ae4e89875a6155667db834a410aaaa2ebe3cf89820556
+
### Custom options
There are various aspects of the plugin that you can configure via options you are passing to the 2 main methods above (`runEager`/`runLazy`).
@@ -140,22 +142,12 @@ You have already seen the `audiences` option in the examples above, but here is
```js
runEager.call(document, {
- // Overrides the base path if the plugin was installed in a sub-directory
- basePath: '',
-
// Lets you configure the prod environment.
// (prod environments do not get the pill overlay)
prodHost: 'www.my-website.com',
// if you have several, or need more complex logic to toggle pill overlay, you can use
- isProd: () => window.location.hostname.endsWith('hlx.page')
- || window.location.hostname === ('localhost'),
-
- /* Generic properties */
- // RUM sampling rate on regular AEM pages is 1 out of 100 page views
- // but we increase this by default for audiences, campaigns and experiments
- // to 1 out of 10 page views so we can collect metrics faster of the relative
- // short durations of those campaigns/experiments
- rumSamplingRate: 10,
+ isProd: () => !window.location.hostname.endsWith('hlx.page')
+ && window.location.hostname !== ('localhost'),
// the storage type used to persist data between page views
// (for instance to remember what variant in an experiment the user was served)
@@ -174,14 +166,41 @@ runEager.call(document, {
/* Experimentation related properties */
// See more details on the dedicated Experiments page linked below
- experimentsRoot: '/experiments',
- experimentsConfigFile: 'manifest.json',
- experimentsMetaTag: 'experiment',
+ experimentsMetaTagPrefix: 'experiment',
experimentsQueryParameter: 'experiment',
-}, pluginContext);
+});
```
For detailed implementation instructions on the different features, please read the dedicated pages we have on those topics:
-- [Audiences](https://github.com/adobe/aem-experimentation/wiki/Audiences)
-- [Campaigns](https://github.com/adobe/aem-experimentation/wiki/Campaigns)
-- [Experiments](https://github.com/adobe/aem-experimentation/wiki/Experiments)
+- [Audiences](/documentation/audiences.md)
+- [Campaigns](/documentation/campaigns.md)
+- [Experiments](/documentation/experiments.md)
+
+## Extensibility & integrations
+
+If you need to further integrate the experimentation plugin with custom analytics reporting or other 3rd-party libraries, you can listen for the `aem:experimentation` event:
+```js
+document.addEventListener('aem:experimentation', (ev) => console.log(ev.detail));
+```
+
+The event details will contain one of 3 possible sets of properties:
+- For experiments:
+ - `type`: `experiment`
+ - `element`: the DOM element that was modified
+ - `experiment`: the experiment name
+ - `variant`: the variant name that was served
+- For audiences:
+ - `type`: `audience`
+ - `element`: the DOM element that was modified
+ - `audience`: the audience that was resolved
+- For campaigns:
+ - `type`: `campaign`
+ - `element`: the DOM element that was modified
+ - `campaign`: the campaign that was resolved
+
+Additionally, you can leverage the following global JS objects `window.hlx.experiments`, `window.hlx.audiences` and `window.hlx.campaigns`.
+Those will each be an array of objects containing:
+ - `type`: one of `page`, `section` or `fragment`
+ - `el`: the DOM element that was modified
+ - `servedExperience`: the URL for the content that was inlined for that experience
+ - `config`: an object containing the config details
diff --git a/plugins/experimentation/documentation/audiences.md b/plugins/experimentation/documentation/audiences.md
new file mode 100644
index 00000000..1caac7b5
--- /dev/null
+++ b/plugins/experimentation/documentation/audiences.md
@@ -0,0 +1,114 @@
+# Using audiences to personalize the experience
+
+## Overview
+
+With audiences you can serve different versions of your content to different groups of users based on the information you can glean from there current session. For instance, you can optimize the experience for:
+- mobile vs. desktop
+- Chrome vs. Firefox
+- 1st vs. returning visitor
+- fast vs slow connections
+- different geographies
+- etc.
+
+## Set up
+
+First, you need to define audiences for the project. This is done directly in the project codebase. Audiences are defined as a `Map` of audience names and boolean evaluating (async) functions that check whether the given audience is resolved in the current browsing session.
+
+You'd typically define the mapping in your AEM's `scripts.js` as follows:
+```js
+const geoPromise = (async () => {
+ const resp = await fetch(/* some geo service*/);
+ return resp.json();
+})();
+
+const AUDIENCES = {
+ mobile: () => window.innerWidth < 600,
+ desktop: () => window.innerWidth >= 600,
+ us: async () => (await geoPromise).region === 'us',
+ eu: async () => (await geoPromise).region === 'eu',
+}
+```
+
+As you can see in the example above, functions need to return a boolean value. If the value is truthy, the audience is considered resolved, and if it's falsy then it isn't. You can also use any browser API directly, or rely on external services to resolve an audience.
+
+:warning: Using external services will have a performance impact on the initial page load as the call will be blocking the page rendering until the async function is fully evaluated.
+
+The audiences for the project then need to be passed to the plugin initialization as follows:
+
+```js
+const { loadEager } = await import('../plugins/experimentation/src/index.js');
+await loadEager(document, { audiences: AUDIENCES });
+```
+
+### Custom options
+
+By default, the audience feature looks at the `Audience` metadata tags and `audience` query parameters, but if this clashes with your existing codebase or doesn't feel intuitive to your authors, you can adjust this by passing new options to the plugin.
+
+For instance, here is an alternate configuration that would use `segment` instead of `audience`:
+```js
+const { loadEager } = await import('../plugins/experimentation/src/index.js');
+await loadEager(document, {
+ audiences: AUDIENCES,
+ audiencesMetaTagPrefix: 'segment',
+ audiencesQueryParameter: 'segment',
+});
+```
+
+## Authoring
+
+Once the above steps are done, your authors are ready to start using audiences for their experiences.
+
+### Page-level audiences
+
+Each Page can have several page-level audiences defined in the page metadata.
+The audiences are set up directly in the page metadata block as follows:
+
+| Metadata | |
+|-------------------|---------------------------------------------------------------|
+| Audience: Mobile | [https://{ref}--{repo}--{org}.hlx.page/my-page-for-mobile]() |
+| Audience: Desktop | [https://{ref}--{repo}--{org}.hlx.page/my-page-for-desktop]() |
+
+The notation is pretty flexible and authors can also use `Audience (Mobile)` or `Audience Mobile` if this is a preferred notation.
+
+### Section-level audiences
+
+Each section in a page can also run any number of audiences. Section-level audiences are run after the page-level audiences have run, i.e. after the variants have been processed and their markup was pulled into the main page, so the section-level audiences that will run are dictated by the document from the current page-level experiment/audience/campaign, and not necessarily just the main page.
+
+Section-level audiences are authored essentially the same way that page-level audiences are, but leverage the `Section Metadata` block instead:
+
+| Section Metadata | |
+|-------------------|---------------------------------------------------------------|
+| Audience: Mobile | [https://{ref}--{repo}--{org}.hlx.page/my-page-for-mobile]() |
+| Audience: Desktop | [https://{ref}--{repo}--{org}.hlx.page/my-page-for-desktop]() |
+
+### Fragment-level audiences
+
+Fragment-level audiences are handled differently than page and section-level audiences. They target a specific CSS selector instead of the whole page or the section. Whenever the desired CSS `selector` is resolved in the DOM tree (i.e. whenever the element is added to the page), the audiences will be run. For AEM, this typically happens even before the `decorate` method from the block's JS file is run.
+
+Fragment-level audiences are also authored differently than page and section-level audiences. First, you need to specify a new metadata entry:
+
+| Metadata | |
+|---------------------|-------------------------------------------------------------------------------|
+| Audience Manifest | [https://{ref}--{repo}--{org}.hlx.page/my-audiences.json?sheet=mobile]() |
+
+The spreadsheet then needs to be defined as follows:
+
+| Page | Audience | Selector | Url |
+|-----------|----------|----------|---------------------------------|
+| /my-page/ | Mobile | .hero | /fragments/my-page-hero-mobile |
+| /my-page/ | Desktop | .hero | /fragments/my-page-hero-desktop |
+
+The same spreadsheet can also contain the configuration for several pages at once. The engine will filter out the entries in the spreadsheet that match the current page.
+
+
+### Simulation
+
+Once all of this is set up, authors will have access to an overlay on `localhost` and on the stage environments (i.e. `*.hlx.page`) that lets them see what audiences have been configured for the page and switch between each to visualize the content variations accordingly.
+
+![audience overlay](./images/audiences-overlay.png)
+
+The simulation capabilities leverage the `audience` query parameter that is appended to the URL and forcibly let you see the specific content variant.
+
+## Development
+
+To help developers in designing variants for each audience, when audiences are resolved on the page it will automatically add a new CSS class named `audience-` for each to the `` element, i.e. `audience-mobile audience-iphone`.
diff --git a/plugins/experimentation/documentation/campaigns.md b/plugins/experimentation/documentation/campaigns.md
new file mode 100644
index 00000000..fe62759b
--- /dev/null
+++ b/plugins/experimentation/documentation/campaigns.md
@@ -0,0 +1,98 @@
+# Running marketing campaigns that personalize the experience
+
+## Overview
+
+With campaigns you can send out emails or social media posts that link back to your site and that will serve specific offers or versions of your content to the targeted audience.
+
+## Set up
+
+The setup is pretty minimal. Once you've instrumented the experimentation plugin in your AEM website, you are essentially good to go.
+
+Just keep in mind that if you want to only target specific audiences for that campaign, you'll also need to set up the [audiences](Audiences) accordingly for your project.
+
+### Custom options
+
+By default, the campaigns feature looks at the `Campaign` metadata tags and `campaign` query parameter, but if this clashes with your existing codebase or doesn't feel intuitive to your authors, you can adjust this by passing new options to the plugin.
+
+For instance, here is an alternate configuration that would use `sale` instead of `campaign`:
+```js
+const { loadEager } = await import('../plugins/experimentation/src/index.js');
+await loadEager(document, {
+ campaignsMetaTagPrefix: 'sale',
+ campaignsQueryParameter: 'sale',
+});
+```
+
+:mega: The campaign feature also supports the industry-standard Urchin Tracking Module (UTM) `utm_campaign` as query parameter. There is nothing special you need to do to get this working and it will be seamlessly handled the same way as the `campaignsQueryParameter`. This means that both:
+
+- [https://{ref}--{repo}--{org}.hlx.page/my-page?campaign=xmas]()
+- [https://{ref}--{repo}--{org}.hlx.page/my-page?utm_campaign=xmas]()
+
+would essentially serve you the `xmas` variant of the experience.
+
+## Authoring
+
+Once the above steps are done, your authors are ready to start using campaigns for their experiences.
+
+### Page-level campaigns
+
+Each Page can have several page-level campaigns defined in the page metadata.
+The campaigns are set up directly in the page metadata block as follows:
+
+| Metadata | |
+|---------------------|-----------------------------------------------------------------|
+| Campaign: Xmas | [https://{ref}--{repo}--{org}.hlx.page/my-page-for-xmas]() |
+| Campaign: Halloween | [https://{ref}--{repo}--{org}.hlx.page/my-page-for-halloween]() |
+
+The notation is pretty flexible and authors can also use `Campaign (Xmas)` or `Campaign Halloween` if this is a preferred notation.
+
+If you wanted to additionally restrict the campaign to specific audiences, so that for instance your campaigns are only accessible on mobile phone or on iPhone, you'd leverage the [audiences](Audiences) feature and use the following metadata:
+
+| Metadata | |
+|---------------------|-----------------------------------------------------------------|
+| Campaign: Xmas | [https://{ref}--{repo}--{org}.hlx.page/my-page-for-xmas]() |
+| Campaign: Halloween | [https://{ref}--{repo}--{org}.hlx.page/my-page-for-halloween]() |
+| Campaign Audience | mobile, iphone |
+
+If any of the listed audiences is resolved, then the campaign will run and the matching content will be served.
+If you needed both audiences to be resolved, you'd define a new `mobile-iphone` audience in your project and use that in the metadata instead.
+
+### Section-level audiences
+
+Each section in a page can also run any number of campaigns. Section-level campaigns are run after the page-level campaigns have run, i.e. after the variants have been processed and their markup was pulled into the main page, so the section-level campaigns that will run are dictated by the document from the current page-level experiment/audience/campaign, and not necessarily just the main page.
+
+Section-level campaigns are authored essentially the same way that page-level campaigns are, but leverage the `Section Metadata` block instead:
+
+| Section Metadata | |
+|---------------------|-----------------------------------------------------------------|
+| Campaign: Xmas | [https://{ref}--{repo}--{org}.hlx.page/my-page-for-xmas]() |
+| Campaign: Halloween | [https://{ref}--{repo}--{org}.hlx.page/my-page-for-halloween]() |
+
+### Fragment-level campaigns
+
+Fragment-level campaigns are handled differently than page and section-level campaigns. They target a specific CSS selector instead of the whole page or the section. Whenever the desired CSS `selector` is resolved in the DOM tree (i.e. whenever the element is added to the page), the campaigns will be run. For AEM, this typically happens even before the `decorate` method from the block's JS file is run.
+
+Fragment-level campaigns are also authored differently than page and section-level campaigns. First, you need to specify a new metadata entry:
+
+| Metadata | |
+|-------------------|------------------------------------------------------------------------|
+| Campaign Manifest | [https://{ref}--{repo}--{org}.hlx.page/my-campaigns.json?sheet=2024]() |
+
+The spreadsheet then needs to be defined as follows:
+
+| Page | Campaign | Selector | Url |
+|-----------|--------------|----------|---------------------------------|
+| /my-page/ | XMas | .hero | /fragments/my-page-hero-xmas |
+| /my-page/ | ThanksGiving | .hero | /fragments/my-page-hero-thxgivn |
+
+The same spreadsheet can also contain the configuration for several pages at once. The engine will filter out the entries in the spreadsheet that match the current page.
+
+### Simulation
+
+Once all of this is set up, authors will have access to an overlay on `localhost` and on the stage environments (i.e. `*.hlx.stage`) that lets them see what campaigns have been configured for the page and switch between each to visualize the content variations accordingly.
+
+![audience overlay](./images/campaigns-overlay.png)
+
+## Development
+
+To help developers in designing variants for each campaign, when a campaign is resolved on the page it will automatically add a new CSS class named `campaign-` to the `` element, i.e. `campaign-xmas`.
diff --git a/plugins/experimentation/documentation/experiments.md b/plugins/experimentation/documentation/experiments.md
new file mode 100644
index 00000000..538f3bcc
--- /dev/null
+++ b/plugins/experimentation/documentation/experiments.md
@@ -0,0 +1,170 @@
+# Running A/B tests to compare variants of an experience
+
+## Overview
+
+With experiments (also called A/B tests) you can randomly serve different versions of your content to your end users to test out alternate experiences or validate conversion hypotheses. For instance, you can:
+- compare how the wording in a hero block impacts the conversion on the call-to-action element
+- compare how 2 different implementations of a specific block impact the overall performance, engagement and/or user conversion
+
+## Set up
+
+The setup is pretty minimal. Once you've instrumented the experimentation plugin in your AEM website, you are essentially good to go.
+
+Just keep in mind that if you want to only target specific audiences for that experiment, you'll also need to set up the [audiences](Audiences) accordingly for your project.
+
+### Custom options
+
+By default, the experiments feature looks at the `Experiment` metadata tags and the `experiment` query parameter, but if this clashes with your existing codebase or doesn't feel intuitive to your authors, you can adjust this by passing new options to the plugin.
+
+For instance, here is an alternate configuration that would use `abtest` instead of `experiment`:
+```js
+const { loadEager } = await import('../plugins/experimentation/src/index.js');
+await loadEager(document, {
+ experimentsMetaTagPrefix: 'abtest',
+ experimentsQueryParameter: 'abtest',
+});
+```
+
+### Tracking custom conversion events
+
+By default, the engine will consider any `click` a conversion. If you want to be more granular in your tests, the plugin integrates with the https://github.com/adobe/aem-rum-conversion plugin as well and will automatically detect its `Conversion Name` property (for both page level and section level metadata).
+
+## Authoring
+
+Once the above steps are done, your authors are ready to start using experiments for their experiences.
+
+### Page-level experiments
+
+Each Page can have 1 page-level experiment that is controlled via the page metadata.
+The experiment is set up directly in the page metadata block as follows:
+
+| Metadata | |
+|---------------------|--------------------------------------------------------------|
+| Experiment | Hero Test |
+| Experiment Variants | [https://{ref}--{repo}--{org}.hlx.page/my-page-variant-1](), [https://{ref}--{repo}--{org}.hlx.page/my-page-variant-2](), [https://{ref}--{repo}--{org}.hlx.page/my-page-variant-3]() |
+
+The page that is instrumented is called the `control`, and the content variations are `variants` or `challengers`.
+Variants are evenly split by default, so the above would give us:
+- 25% for the control (the page that has the metadata)
+- 25% for each of the 3 variants that are defined
+
+If you want to control the split ratio, you can use:
+
+| Metadata | |
+|---------------------|--------------------------------------------------------------|
+| Experiment | Hero Test |
+| Experiment Variants | [https://{ref}--{repo}--{org}.hlx.page/my-page-variant-1](), [https://{ref}--{repo}--{org}.hlx.page/my-page-variant-2](), [https://{ref}--{repo}--{org}.hlx.page/my-page-variant-3]() |
+| Experiment Split | 10, 20, 30 |
+
+This would give us the following split:
+
+- 10% on variant 1
+- 20% on variant 2
+- 30% on variant 3
+- 40% on the control (i.e 100% - 10% - 20% - 30% = 40%)
+
+A `30, 30, 40` split, would respectively give us:
+
+- 30% on variant 1
+- 30% on variant 2
+- 40% on variant 3
+- 0% on the control (i.e 100% - 30% - 30% - 40% = 0%)
+
+which would essentially disable the control page.
+
+If you need to be really granular, decimal numbers are also supported, like `33.34, 33.33, 33.33`.
+
+#### Code-level experiments
+
+Note that the above assumes you have different content variants to serve, but if you want to run a pure code-based A/B Test, this is also achievable via:
+
+| Metadata | |
+|---------------------|-----------|
+| Experiment | Hero Test |
+| Experiment Variants | 2 |
+
+This will create just 2 variants, without touching the content, and you'll be able to target those based on the `experiment-hero-test` and `variant-control`/`variant-challenger-1`/`variant-challenger-2` CSS classes that will be set on the `` element
+
+#### Audience-based experiments
+
+If you wanted to additionally restrict the experiments to specific audiences, so that for instance your experiment is only run on iPad or on iPhone, you'd leverage the [audiences](Audiences) feature and use the following metadata:
+
+| Metadata | |
+|---------------------|--------------------------------------------------------------|
+| Experiment | Hero Test |
+| Experiment Variants | [https://{ref}--{repo}--{org}.hlx.page/my-page-variant-1](), [https://{ref}--{repo}--{org}.hlx.page/my-page-variant-2](), [https://{ref}--{repo}--{org}.hlx.page/my-page-variant-3]() |
+| Experiment Audience | iPad, iPhone |
+
+If any of the listed audiences is resolved, then the experiment will run and the matching content will be served. The list is essentially treated as an "or".
+If you needed both audiences to be resolved (i.e. treated as "and"), for say a "US" audience and the "iPad" audience, you'd define a new custom "us-ipad" audience in your project that checks for both conditions and use that in the metadata instead.
+
+#### Time bound experiments
+
+You can also specify start and end dates, as well as toggle the experiment status.
+
+| Metadata | |
+|-----------------------|--------------------------------------------------------------|
+| Experiment | Hero Test |
+| Experiment Variants | [https://{ref}--{repo}--{org}.hlx.page/my-page-variant-1](), [https://{ref}--{repo}--{org}.hlx.page/my-page-variant-2](), [https://{ref}--{repo}--{org}.hlx.page/my-page-variant-3]() |
+| Experiment Status | Active |
+| Experiment Start Date | 2024-01-01 |
+| Experiment End Date | 2024-03-31 |
+
+The status defaults to `Active`, and supports `Active`/`True`/`On` as well as `Inactive`/`False`/`Off`.
+Start and end dates are in the flexible JS [Date Time String Format](https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date-time-string-format). If the start and/or end dates are specified, the experiment will not run if the user's time lies outside the given window.
+
+So you can both use generic dates, like `2024-01-31` or `2024/01/31`, and time-specific dates like `2024-01-31T13:37` or `2024/01/31 1:37 pm`. You can even enforce a specific timezone so your experiment activates when, say, it's 2am GMT+1 by using `2024/1/31 2:00 pm GMT+1` or similar notations.
+
+### Section-level experiments
+
+Each section in a page can also run 1 experiment, so you can have as many section-level experiments as you have sections.
+Section-level experiments are run after the page-level experiment has run, i.e. after the variant has been processed and its markup pulled into the main page, so the section-level experiments that will run are dictated by the document from the current page-level experiment/audience/campaign, and not necessarily just the control page.
+
+Section-level experiments are authored essentially the same way that page-level experiments are, but leverage the `Section Metadata` block instead:
+
+| Section Metadata | |
+|---------------------|--------------------------------------------------------------|
+| Experiment | Hero Test |
+| Experiment Variants | [https://{ref}--{repo}--{org}.hlx.page/my-page-variant-1](), [https://{ref}--{repo}--{org}.hlx.page/my-page-variant-2](), [https://{ref}--{repo}--{org}.hlx.page/my-page-variant-3]() |
+
+### Fragment-level experiments
+
+Fragment-level experiments are handled differently than page and section-level experiments. You can essentially have as many you want and they can target any CSS selector. Whenever the desired CSS `selector` is resolved in the DOM tree (i.e. whenever the element is added to the page), the experiment will be run. For AEM, this typically happens even before the `decorate` method from the block's JS file is run.
+
+Fragment-level experiments are also authored differently than page and section-level experiments. First, you need to specify a new metadata entry:
+
+| Metadata | |
+|---------------------|-------------------------------------------------------------------------------|
+| Experiment Manifest | [https://{ref}--{repo}--{org}.hlx.page/my-experiments.json?sheet=hero-test]() |
+
+The spreadsheet then needs to be defined as follows:
+
+| Page | Experiment | Variant | Selector | Url |
+|-----------|------------|--------------|----------|-----------------------------------|
+| /my-page/ | Hero Test | Challenger 1 | .hero | /fragments/my-page-hero-variant-1 |
+| /my-page/ | Hero Test | Challenger 2 | .hero | /fragments/my-page-hero-variant-2 |
+| /my-page/ | Hero Test | Challenger 3 | .hero | /fragments/my-page-hero-variant-3 |
+
+Like with regular experiments, you can also define the `Split`, `Start Date`, `End Date`, etc.
+
+The same spreadsheet can also contain the configuration for several pages at once. The engine will filter out the entries in the spreadsheet that match the current page
+
+### Simulation
+
+Once all of this is set up, authors will have access to an overlay on `localhost` and on the stage environments (i.e. `*.hlx.stage`) that lets them see what experiment and variants have been configured for the page and switch between each to visualize the content variations accordingly.
+
+![audience overlay](./images/experiments-overlay.png)
+
+The simulation capabilities leverage the `audience` query parameter that is appended to the URL and forcibly let you see the specific content variant.
+
+### Inline Reporting
+
+AEM Experiments performance is automatically tracked via RUM data, and can be reported directly in the overlay pill UI. Since the RUM data is not public, you'll need to obtain a **domain key** for your website and configure the pill accordingly for the data to show up.
+
+1. Generate a domain key for your site using https://aemcs-workspace.adobe.com/rum/generate-domain-key (make sure to use exactly the same domain name that you used in your project config for go-live)
+2. Click the ⚙️ icon in the pill header, and paste the provided domain key in the popup dialog
+ - alternatively, you can also just run `window.localStorage.setItem('aem-domainkey', )` in the JS console
+
+## Development
+
+To help developers in designing variants for each experiment, when an experiment is running on the page it will automatically add new CSS classes named `experiment-` and `variant-` to the `` element, i.e. `experiment-hero variant-fullpage`.
diff --git a/plugins/experimentation/documentation/images/audiences-overlay.png b/plugins/experimentation/documentation/images/audiences-overlay.png
new file mode 100644
index 00000000..7788a28d
Binary files /dev/null and b/plugins/experimentation/documentation/images/audiences-overlay.png differ
diff --git a/plugins/experimentation/documentation/images/campaigns-overlay.png b/plugins/experimentation/documentation/images/campaigns-overlay.png
new file mode 100644
index 00000000..c2b41cd7
Binary files /dev/null and b/plugins/experimentation/documentation/images/campaigns-overlay.png differ
diff --git a/plugins/experimentation/documentation/images/experiments-overlay.png b/plugins/experimentation/documentation/images/experiments-overlay.png
new file mode 100644
index 00000000..a8e19ae1
Binary files /dev/null and b/plugins/experimentation/documentation/images/experiments-overlay.png differ
diff --git a/plugins/experimentation/package-lock.json b/plugins/experimentation/package-lock.json
index 30b8d3e7..86c031f9 100644
--- a/plugins/experimentation/package-lock.json
+++ b/plugins/experimentation/package-lock.json
@@ -1,18 +1,25 @@
{
"name": "@adobe/aem-experimentation",
- "version": "1.0.0",
+ "version": "1.15.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@adobe/aem-experimentation",
- "version": "1.0.0",
+ "version": "1.15.1",
"license": "Apache-2.0",
"devDependencies": {
"@babel/eslint-parser": "7.22.15",
+ "@playwright/test": "1.44.0",
+ "@semantic-release/changelog": "6.0.3",
+ "@semantic-release/git": "10.0.1",
+ "@semantic-release/npm": "12.0.1",
"eslint": "8.48.0",
"eslint-config-airbnb-base": "15.0.0",
"eslint-plugin-import": "2.28.1",
+ "http-server": "14.1.1",
+ "monocart-coverage-reports": "2.8.2",
+ "semantic-release": "23.1.1",
"stylelint": "15.10.3",
"stylelint-config-standard": "34.0.0"
}
@@ -41,89 +48,18 @@
}
},
"node_modules/@babel/code-frame": {
- "version": "7.22.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
- "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
+ "version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.6.tgz",
+ "integrity": "sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA==",
"dev": true,
"dependencies": {
- "@babel/highlight": "^7.22.13",
- "chalk": "^2.4.2"
+ "@babel/highlight": "^7.24.6",
+ "picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
- "node_modules/@babel/code-frame/node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/@babel/code-frame/node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/@babel/code-frame/node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dev": true,
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/@babel/code-frame/node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "dev": true
- },
- "node_modules/@babel/code-frame/node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "dev": true,
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/@babel/code-frame/node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/@babel/code-frame/node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/@babel/compat-data": {
"version": "7.22.20",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.20.tgz",
@@ -206,15 +142,15 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
- "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
+ "version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.6.tgz",
+ "integrity": "sha512-S7m4eNa6YAPJRHmKsLHIDJhNAGNKoWNiWefz1MBbpnt8g9lvMDl1hir4P9bo/57bQEmuwEhnRU/AMWsD0G/Fbg==",
"dev": true,
"peer": true,
"dependencies": {
- "@babel/types": "^7.23.0",
- "@jridgewell/gen-mapping": "^0.3.2",
- "@jridgewell/trace-mapping": "^0.3.17",
+ "@babel/types": "^7.24.6",
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^2.5.1"
},
"engines": {
@@ -256,9 +192,9 @@
"peer": true
},
"node_modules/@babel/helper-environment-visitor": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
- "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+ "version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.6.tgz",
+ "integrity": "sha512-Y50Cg3k0LKLMjxdPjIl40SdJgMB85iXn27Vk/qbHZCFx/o5XO3PSnpi675h1KEmmDb6OFArfd5SCQEQ5Q4H88g==",
"dev": true,
"peer": true,
"engines": {
@@ -266,27 +202,27 @@
}
},
"node_modules/@babel/helper-function-name": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
- "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+ "version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.6.tgz",
+ "integrity": "sha512-xpeLqeeRkbxhnYimfr2PC+iA0Q7ljX/d1eZ9/inYbmfG2jpl8Lu3DyXvpOAnrS5kxkfOWJjioIMQsaMBXFI05w==",
"dev": true,
"peer": true,
"dependencies": {
- "@babel/template": "^7.22.15",
- "@babel/types": "^7.23.0"
+ "@babel/template": "^7.24.6",
+ "@babel/types": "^7.24.6"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-hoist-variables": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
- "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+ "version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.6.tgz",
+ "integrity": "sha512-SF/EMrC3OD7dSta1bLJIlrsVxwtd0UpjRJqLno6125epQMJ/kyFmpTT4pbvPbdQHzCHg+biQ7Syo8lnDtbR+uA==",
"dev": true,
"peer": true,
"dependencies": {
- "@babel/types": "^7.22.5"
+ "@babel/types": "^7.24.6"
},
"engines": {
"node": ">=6.9.0"
@@ -339,22 +275,22 @@
}
},
"node_modules/@babel/helper-split-export-declaration": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
- "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+ "version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.6.tgz",
+ "integrity": "sha512-CvLSkwXGWnYlF9+J3iZUvwgAxKiYzK3BWuo+mLzD/MDGOZDj7Gq8+hqaOkMxmJwmlv0iu86uH5fdADd9Hxkymw==",
"dev": true,
"peer": true,
"dependencies": {
- "@babel/types": "^7.22.5"
+ "@babel/types": "^7.24.6"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
- "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
+ "version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.6.tgz",
+ "integrity": "sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==",
"dev": true,
"peer": true,
"engines": {
@@ -362,9 +298,9 @@
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
- "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.6.tgz",
+ "integrity": "sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==",
"dev": true,
"engines": {
"node": ">=6.9.0"
@@ -396,14 +332,15 @@
}
},
"node_modules/@babel/highlight": {
- "version": "7.22.13",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz",
- "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==",
+ "version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.6.tgz",
+ "integrity": "sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ==",
"dev": true,
"dependencies": {
- "@babel/helper-validator-identifier": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.24.6",
"chalk": "^2.4.2",
- "js-tokens": "^4.0.0"
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
@@ -481,9 +418,9 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
- "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
+ "version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.6.tgz",
+ "integrity": "sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==",
"dev": true,
"peer": true,
"bin": {
@@ -494,36 +431,36 @@
}
},
"node_modules/@babel/template": {
- "version": "7.22.15",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
- "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+ "version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.6.tgz",
+ "integrity": "sha512-3vgazJlLwNXi9jhrR1ef8qiB65L1RK90+lEQwv4OxveHnqC3BfmnHdgySwRLzf6akhlOYenT+b7AfWq+a//AHw==",
"dev": true,
"peer": true,
"dependencies": {
- "@babel/code-frame": "^7.22.13",
- "@babel/parser": "^7.22.15",
- "@babel/types": "^7.22.15"
+ "@babel/code-frame": "^7.24.6",
+ "@babel/parser": "^7.24.6",
+ "@babel/types": "^7.24.6"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.0.tgz",
- "integrity": "sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw==",
+ "version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.6.tgz",
+ "integrity": "sha512-OsNjaJwT9Zn8ozxcfoBc+RaHdj3gFmCmYoQLUII1o6ZrUwku0BMg80FoOTPx+Gi6XhcQxAYE4xyjPTo4SxEQqw==",
"dev": true,
"peer": true,
"dependencies": {
- "@babel/code-frame": "^7.22.13",
- "@babel/generator": "^7.23.0",
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-hoist-variables": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
- "@babel/parser": "^7.23.0",
- "@babel/types": "^7.23.0",
- "debug": "^4.1.0",
+ "@babel/code-frame": "^7.24.6",
+ "@babel/generator": "^7.24.6",
+ "@babel/helper-environment-visitor": "^7.24.6",
+ "@babel/helper-function-name": "^7.24.6",
+ "@babel/helper-hoist-variables": "^7.24.6",
+ "@babel/helper-split-export-declaration": "^7.24.6",
+ "@babel/parser": "^7.24.6",
+ "@babel/types": "^7.24.6",
+ "debug": "^4.3.1",
"globals": "^11.1.0"
},
"engines": {
@@ -541,20 +478,30 @@
}
},
"node_modules/@babel/types": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
- "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
+ "version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.6.tgz",
+ "integrity": "sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==",
"dev": true,
"peer": true,
"dependencies": {
- "@babel/helper-string-parser": "^7.22.5",
- "@babel/helper-validator-identifier": "^7.22.20",
+ "@babel/helper-string-parser": "^7.24.6",
+ "@babel/helper-validator-identifier": "^7.24.6",
"to-fast-properties": "^2.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
+ "node_modules/@colors/colors": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
+ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.1.90"
+ }
+ },
"node_modules/@csstools/css-parser-algorithms": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.1.tgz",
@@ -731,15 +678,15 @@
"dev": true
},
"node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
- "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+ "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
"dev": true,
"peer": true,
"dependencies": {
- "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
@@ -756,9 +703,9 @@
}
},
"node_modules/@jridgewell/set-array": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"dev": true,
"peer": true,
"engines": {
@@ -773,9 +720,9 @@
"peer": true
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.19",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
- "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"dev": true,
"peer": true,
"dependencies": {
@@ -849,1167 +796,1105 @@
"node": ">= 8"
}
},
- "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==",
- "dev": true
- },
- "node_modules/@types/minimist": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
- "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==",
- "dev": true
- },
- "node_modules/@types/normalize-package-data": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
- "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
- "dev": true
- },
- "node_modules/acorn": {
- "version": "8.10.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
- "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
+ "node_modules/@octokit/auth-token": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.1.tgz",
+ "integrity": "sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==",
"dev": true,
- "bin": {
- "acorn": "bin/acorn"
- },
"engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/acorn-jsx": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
- "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
- "dev": true,
- "peerDependencies": {
- "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ "node": ">= 18"
}
},
- "node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "node_modules/@octokit/core": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.2.tgz",
+ "integrity": "sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==",
"dev": true,
"dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
+ "@octokit/auth-token": "^5.0.0",
+ "@octokit/graphql": "^8.0.0",
+ "@octokit/request": "^9.0.0",
+ "@octokit/request-error": "^6.0.1",
+ "@octokit/types": "^13.0.0",
+ "before-after-hook": "^3.0.2",
+ "universal-user-agent": "^7.0.0"
},
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
+ "engines": {
+ "node": ">= 18"
}
},
- "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/@octokit/endpoint": {
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.1.tgz",
+ "integrity": "sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==",
"dev": true,
+ "dependencies": {
+ "@octokit/types": "^13.0.0",
+ "universal-user-agent": "^7.0.2"
+ },
"engines": {
- "node": ">=8"
+ "node": ">= 18"
}
},
- "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==",
+ "node_modules/@octokit/graphql": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.1.1.tgz",
+ "integrity": "sha512-ukiRmuHTi6ebQx/HFRCXKbDlOh/7xEV6QUXaE7MJEKGNAncGI/STSbOkl12qVXZrfZdpXctx5O9X1AIaebiDBg==",
"dev": true,
"dependencies": {
- "color-convert": "^2.0.1"
+ "@octokit/request": "^9.0.0",
+ "@octokit/types": "^13.0.0",
+ "universal-user-agent": "^7.0.0"
},
"engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ "node": ">= 18"
}
},
- "node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "node_modules/@octokit/openapi-types": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz",
+ "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==",
"dev": true
},
- "node_modules/array-buffer-byte-length": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz",
- "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==",
+ "node_modules/@octokit/plugin-paginate-rest": {
+ "version": "11.3.0",
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.0.tgz",
+ "integrity": "sha512-n4znWfRinnUQF6TPyxs7EctSAA3yVSP4qlJP2YgI3g9d4Ae2n5F3XDOjbUluKRxPU3rfsgpOboI4O4VtPc6Ilg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "is-array-buffer": "^3.0.1"
+ "@octokit/types": "^13.5.0"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "engines": {
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "@octokit/core": ">=6"
}
},
- "node_modules/array-includes": {
- "version": "3.1.6",
- "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz",
- "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==",
+ "node_modules/@octokit/plugin-retry": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-7.1.1.tgz",
+ "integrity": "sha512-G9Ue+x2odcb8E1XIPhaFBnTTIrrUDfXN05iFXiqhR+SeeeDMMILcAnysOsxUpEWcQp2e5Ft397FCXTcPkiPkLw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4",
- "get-intrinsic": "^1.1.3",
- "is-string": "^1.0.7"
+ "@octokit/request-error": "^6.0.0",
+ "@octokit/types": "^13.0.0",
+ "bottleneck": "^2.15.3"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">= 18"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "peerDependencies": {
+ "@octokit/core": ">=6"
}
},
- "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==",
+ "node_modules/@octokit/plugin-throttling": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.3.0.tgz",
+ "integrity": "sha512-B5YTToSRTzNSeEyssnrT7WwGhpIdbpV9NKIs3KyTWHX6PhpYn7gqF/+lL3BvsASBM3Sg5BAUYk7KZx5p/Ec77w==",
"dev": true,
+ "dependencies": {
+ "@octokit/types": "^13.0.0",
+ "bottleneck": "^2.15.3"
+ },
"engines": {
- "node": ">=8"
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "@octokit/core": "^6.0.0"
}
},
- "node_modules/array.prototype.findlastindex": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.2.tgz",
- "integrity": "sha512-tb5thFFlUcp7NdNF6/MpDk/1r/4awWG1FIz3YqDf+/zJSTezBb+/5WViH41obXULHVpDzoiCLpJ/ZO9YbJMsdw==",
+ "node_modules/@octokit/request": {
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.1.1.tgz",
+ "integrity": "sha512-pyAguc0p+f+GbQho0uNetNQMmLG1e80WjkIaqqgUkihqUp0boRU6nKItXO4VWnr+nbZiLGEyy4TeKRwqaLvYgw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4",
- "es-shim-unscopables": "^1.0.0",
- "get-intrinsic": "^1.1.3"
+ "@octokit/endpoint": "^10.0.0",
+ "@octokit/request-error": "^6.0.1",
+ "@octokit/types": "^13.1.0",
+ "universal-user-agent": "^7.0.2"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">= 18"
}
},
- "node_modules/array.prototype.flat": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz",
- "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==",
+ "node_modules/@octokit/request-error": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.1.tgz",
+ "integrity": "sha512-1mw1gqT3fR/WFvnoVpY/zUM2o/XkMs/2AszUUG9I69xn0JFLv6PGkPhNk5lbfvROs79wiS0bqiJNxfCZcRJJdg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4",
- "es-shim-unscopables": "^1.0.0"
+ "@octokit/types": "^13.0.0"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">= 18"
}
},
- "node_modules/array.prototype.flatmap": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz",
- "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==",
+ "node_modules/@octokit/types": {
+ "version": "13.5.0",
+ "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.5.0.tgz",
+ "integrity": "sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4",
- "es-shim-unscopables": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "@octokit/openapi-types": "^22.2.0"
}
},
- "node_modules/arraybuffer.prototype.slice": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz",
- "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==",
+ "node_modules/@playwright/test": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.44.0.tgz",
+ "integrity": "sha512-rNX5lbNidamSUorBhB4XZ9SQTjAqfe5M+p37Z8ic0jPFBMo5iCtQz1kRWkEMg+rYOKSlVycpQmpqjSFq7LXOfg==",
"dev": true,
"dependencies": {
- "array-buffer-byte-length": "^1.0.0",
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "get-intrinsic": "^1.2.1",
- "is-array-buffer": "^3.0.2",
- "is-shared-array-buffer": "^1.0.2"
+ "playwright": "1.44.0"
},
- "engines": {
- "node": ">= 0.4"
+ "bin": {
+ "playwright": "cli.js"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "engines": {
+ "node": ">=16"
}
},
- "node_modules/arrify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
- "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
+ "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,
"engines": {
- "node": ">=0.10.0"
+ "node": ">=12.22.0"
}
},
- "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==",
+ "node_modules/@pnpm/network.ca-file": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz",
+ "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==",
"dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/available-typed-arrays": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
- "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
- "dev": true,
- "engines": {
- "node": ">= 0.4"
+ "dependencies": {
+ "graceful-fs": "4.2.10"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "engines": {
+ "node": ">=12.22.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==",
+ "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
},
- "node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "node_modules/@pnpm/npm-conf": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz",
+ "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==",
"dev": true,
"dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
+ "@pnpm/config.env-replace": "^1.1.0",
+ "@pnpm/network.ca-file": "^1.0.1",
+ "config-chain": "^1.1.11"
+ },
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "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
+ },
+ "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,
"dependencies": {
- "fill-range": "^7.0.1"
+ "@semantic-release/error": "^3.0.0",
+ "aggregate-error": "^3.0.0",
+ "fs-extra": "^11.0.0",
+ "lodash": "^4.17.4"
},
"engines": {
- "node": ">=8"
+ "node": ">=14.17"
+ },
+ "peerDependencies": {
+ "semantic-release": ">=18.0.0"
}
},
- "node_modules/browserslist": {
- "version": "4.22.1",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
- "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
+ "node_modules/@semantic-release/changelog/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,
- "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"
- }
- ],
- "peer": true,
- "dependencies": {
- "caniuse-lite": "^1.0.30001541",
- "electron-to-chromium": "^1.4.535",
- "node-releases": "^2.0.13",
- "update-browserslist-db": "^1.0.13"
- },
- "bin": {
- "browserslist": "cli.js"
- },
"engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ "node": ">=14.17"
}
},
- "node_modules/call-bind": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
- "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "node_modules/@semantic-release/changelog/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,
"dependencies": {
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.0.2"
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "engines": {
+ "node": ">=8"
}
},
- "node_modules/callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "node_modules/@semantic-release/changelog/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,
"engines": {
"node": ">=6"
}
},
- "node_modules/camelcase": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
- "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "node_modules/@semantic-release/changelog/node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
"dev": true,
"engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": ">=8"
}
},
- "node_modules/camelcase-keys": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz",
- "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==",
+ "node_modules/@semantic-release/commit-analyzer": {
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-12.0.0.tgz",
+ "integrity": "sha512-qG+md5gdes+xa8zP7lIo1fWE17zRdO8yMCaxh9lyL65TQleoSv8WHHOqRURfghTytUh+NpkSyBprQ5hrkxOKVQ==",
"dev": true,
"dependencies": {
- "camelcase": "^6.3.0",
- "map-obj": "^4.1.0",
- "quick-lru": "^5.1.1",
- "type-fest": "^1.2.1"
+ "conventional-changelog-angular": "^7.0.0",
+ "conventional-commits-filter": "^4.0.0",
+ "conventional-commits-parser": "^5.0.0",
+ "debug": "^4.0.0",
+ "import-from-esm": "^1.0.3",
+ "lodash-es": "^4.17.21",
+ "micromatch": "^4.0.2"
},
"engines": {
- "node": ">=12"
+ "node": ">=20.8.1"
},
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "peerDependencies": {
+ "semantic-release": ">=20.1.0"
}
},
- "node_modules/camelcase-keys/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==",
+ "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,
"engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": ">=18"
}
},
- "node_modules/caniuse-lite": {
- "version": "1.0.30001543",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001543.tgz",
- "integrity": "sha512-qxdO8KPWPQ+Zk6bvNpPeQIOH47qZSYdFZd6dXQzb2KzhnSXju4Kd7H1PkSJx6NICSMgo/IhRZRhhfPTHYpJUCA==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "peer": true
- },
- "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/@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,
"dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.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"
},
"engines": {
- "node": ">=10"
+ "node": ">=14.17"
},
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
+ "peerDependencies": {
+ "semantic-release": ">=18.0.0"
}
},
- "node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "node_modules/@semantic-release/git/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,
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/@semantic-release/git/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,
"dependencies": {
- "color-name": "~1.1.4"
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
},
"engines": {
- "node": ">=7.0.0"
+ "node": ">=8"
}
},
- "node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/colord": {
- "version": "2.9.3",
- "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
- "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
- "dev": true
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
- },
- "node_modules/confusing-browser-globals": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz",
- "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==",
- "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==",
+ "node_modules/@semantic-release/git/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,
- "peer": true
+ "engines": {
+ "node": ">=6"
+ }
},
- "node_modules/cosmiconfig": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz",
- "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==",
+ "node_modules/@semantic-release/git/node_modules/execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
"dev": true,
"dependencies": {
- "import-fresh": "^3.2.1",
- "js-yaml": "^4.1.0",
- "parse-json": "^5.0.0",
- "path-type": "^4.0.0"
+ "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": ">=14"
+ "node": ">=10"
},
"funding": {
- "url": "https://github.com/sponsors/d-fischer"
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
- "node_modules/cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "node_modules/@semantic-release/git/node_modules/human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
"dev": true,
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
"engines": {
- "node": ">= 8"
+ "node": ">=10.17.0"
}
},
- "node_modules/css-functions-list": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.0.tgz",
- "integrity": "sha512-d/jBMPyYybkkLVypgtGv12R+pIFw4/f/IHtCTxWpZc8ofTYOPigIgmA6vu5rMHartZC+WuXhBUHfnyNUIQSYrg==",
+ "node_modules/@semantic-release/git/node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
"dev": true,
"engines": {
- "node": ">=12.22"
+ "node": ">=8"
}
},
- "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==",
+ "node_modules/@semantic-release/git/node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
"dev": true,
- "dependencies": {
- "mdn-data": "2.0.30",
- "source-map-js": "^1.0.1"
+ "engines": {
+ "node": ">=8"
},
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/git/node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
"engines": {
- "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
+ "node": ">=6"
}
},
- "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/@semantic-release/git/node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
"dev": true,
- "bin": {
- "cssesc": "bin/cssesc"
+ "dependencies": {
+ "path-key": "^3.0.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=8"
}
},
- "node_modules/debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "node_modules/@semantic-release/git/node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"dev": true,
"dependencies": {
- "ms": "2.1.2"
+ "mimic-fn": "^2.1.0"
},
"engines": {
- "node": ">=6.0"
+ "node": ">=6"
},
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/decamelize": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz",
- "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==",
+ "node_modules/@semantic-release/git/node_modules/p-reduce": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz",
+ "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==",
"dev": true,
"engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": ">=8"
}
},
- "node_modules/decamelize-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
- "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
+ "node_modules/@semantic-release/git/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
+ },
+ "node_modules/@semantic-release/git/node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@semantic-release/github": {
+ "version": "10.0.5",
+ "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-10.0.5.tgz",
+ "integrity": "sha512-hmuCDkfru/Uc9+ZBNOSremAupu6BCslvOVDiG0wYcL8TQodCycp6uvwDyeym1H0M4l3ob9c0s0xMBiZjjXQ2yA==",
"dev": true,
"dependencies": {
- "decamelize": "^1.1.0",
- "map-obj": "^1.0.0"
+ "@octokit/core": "^6.0.0",
+ "@octokit/plugin-paginate-rest": "^11.0.0",
+ "@octokit/plugin-retry": "^7.0.0",
+ "@octokit/plugin-throttling": "^9.0.0",
+ "@semantic-release/error": "^4.0.0",
+ "aggregate-error": "^5.0.0",
+ "debug": "^4.3.4",
+ "dir-glob": "^3.0.1",
+ "globby": "^14.0.0",
+ "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",
+ "url-join": "^5.0.0"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=20.8.1"
+ },
+ "peerDependencies": {
+ "semantic-release": ">=20.1.0"
+ }
+ },
+ "node_modules/@semantic-release/github/node_modules/@sindresorhus/merge-streams": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz",
+ "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/decamelize-keys/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==",
+ "node_modules/@semantic-release/github/node_modules/globby": {
+ "version": "14.0.1",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.1.tgz",
+ "integrity": "sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==",
"dev": true,
+ "dependencies": {
+ "@sindresorhus/merge-streams": "^2.1.0",
+ "fast-glob": "^3.3.2",
+ "ignore": "^5.2.4",
+ "path-type": "^5.0.0",
+ "slash": "^5.1.0",
+ "unicorn-magic": "^0.1.0"
+ },
"engines": {
- "node": ">=0.10.0"
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/decamelize-keys/node_modules/map-obj": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
- "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
+ "node_modules/@semantic-release/github/node_modules/path-type": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz",
+ "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==",
"dev": true,
"engines": {
- "node": ">=0.10.0"
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/deep-is": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
- "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
- "dev": true
- },
- "node_modules/define-properties": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz",
- "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==",
+ "node_modules/@semantic-release/github/node_modules/slash": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
+ "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
"dev": true,
- "dependencies": {
- "has-property-descriptors": "^1.0.0",
- "object-keys": "^1.1.1"
- },
"engines": {
- "node": ">= 0.4"
+ "node": ">=14.16"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "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==",
+ "node_modules/@semantic-release/npm": {
+ "version": "12.0.1",
+ "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-12.0.1.tgz",
+ "integrity": "sha512-/6nntGSUGK2aTOI0rHPwY3ZjgY9FkXmEHbW9Kr+62NVOsyqpKKeP0lrCH+tphv+EsNdJNmqqwijTEnVWUMQ2Nw==",
"dev": true,
"dependencies": {
- "path-type": "^4.0.0"
+ "@semantic-release/error": "^4.0.0",
+ "aggregate-error": "^5.0.0",
+ "execa": "^9.0.0",
+ "fs-extra": "^11.0.0",
+ "lodash-es": "^4.17.21",
+ "nerf-dart": "^1.0.0",
+ "normalize-url": "^8.0.0",
+ "npm": "^10.5.0",
+ "rc": "^1.2.8",
+ "read-pkg": "^9.0.0",
+ "registry-auth-token": "^5.0.0",
+ "semver": "^7.1.2",
+ "tempy": "^3.0.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=20.8.1"
+ },
+ "peerDependencies": {
+ "semantic-release": ">=20.1.0"
}
},
- "node_modules/doctrine": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
- "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "node_modules/@semantic-release/npm/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,
"dependencies": {
- "esutils": "^2.0.2"
+ "lru-cache": "^10.0.1"
},
"engines": {
- "node": ">=6.0.0"
+ "node": "^16.14.0 || >=18.0.0"
}
},
- "node_modules/electron-to-chromium": {
- "version": "1.4.539",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.539.tgz",
- "integrity": "sha512-wRmWJ8F7rgmINuI32S6r2SLrw/h/bJQsDSvBiq9GBfvc2Lh73qTOwn73r3Cf67mjVgFGJYcYtmERzySa5jIWlg==",
- "dev": true,
- "peer": true
- },
- "node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "node_modules/error-ex": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
- "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "node_modules/@semantic-release/npm/node_modules/lru-cache": {
+ "version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz",
+ "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==",
"dev": true,
- "dependencies": {
- "is-arrayish": "^0.2.1"
+ "engines": {
+ "node": "14 || >=16.14"
}
},
- "node_modules/es-abstract": {
- "version": "1.22.1",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz",
- "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==",
+ "node_modules/@semantic-release/npm/node_modules/normalize-package-data": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.1.tgz",
+ "integrity": "sha512-6rvCfeRW+OEZagAB4lMLSNuTNYZWLVtKccK79VSTf//yTY5VOCgcpH80O+bZK8Neps7pUnd5G+QlMg1yV/2iZQ==",
"dev": true,
"dependencies": {
- "array-buffer-byte-length": "^1.0.0",
- "arraybuffer.prototype.slice": "^1.0.1",
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.2",
- "es-set-tostringtag": "^2.0.1",
- "es-to-primitive": "^1.2.1",
- "function.prototype.name": "^1.1.5",
- "get-intrinsic": "^1.2.1",
- "get-symbol-description": "^1.0.0",
- "globalthis": "^1.0.3",
- "gopd": "^1.0.1",
- "has": "^1.0.3",
- "has-property-descriptors": "^1.0.0",
- "has-proto": "^1.0.1",
- "has-symbols": "^1.0.3",
- "internal-slot": "^1.0.5",
- "is-array-buffer": "^3.0.2",
- "is-callable": "^1.2.7",
- "is-negative-zero": "^2.0.2",
- "is-regex": "^1.1.4",
- "is-shared-array-buffer": "^1.0.2",
- "is-string": "^1.0.7",
- "is-typed-array": "^1.1.10",
- "is-weakref": "^1.0.2",
- "object-inspect": "^1.12.3",
- "object-keys": "^1.1.1",
- "object.assign": "^4.1.4",
- "regexp.prototype.flags": "^1.5.0",
- "safe-array-concat": "^1.0.0",
- "safe-regex-test": "^1.0.0",
- "string.prototype.trim": "^1.2.7",
- "string.prototype.trimend": "^1.0.6",
- "string.prototype.trimstart": "^1.0.6",
- "typed-array-buffer": "^1.0.0",
- "typed-array-byte-length": "^1.0.0",
- "typed-array-byte-offset": "^1.0.0",
- "typed-array-length": "^1.0.4",
- "unbox-primitive": "^1.0.2",
- "which-typed-array": "^1.1.10"
+ "hosted-git-info": "^7.0.0",
+ "is-core-module": "^2.8.1",
+ "semver": "^7.3.5",
+ "validate-npm-package-license": "^3.0.4"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": "^16.14.0 || >=18.0.0"
}
},
- "node_modules/es-set-tostringtag": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
- "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
+ "node_modules/@semantic-release/npm/node_modules/parse-json": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz",
+ "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==",
"dev": true,
"dependencies": {
- "get-intrinsic": "^1.1.3",
- "has": "^1.0.3",
- "has-tostringtag": "^1.0.0"
+ "@babel/code-frame": "^7.22.13",
+ "index-to-position": "^0.1.2",
+ "type-fest": "^4.7.1"
},
"engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-shim-unscopables": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz",
- "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==",
- "dev": true,
- "dependencies": {
- "has": "^1.0.3"
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/es-to-primitive": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
- "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "node_modules/@semantic-release/npm/node_modules/read-pkg": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz",
+ "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==",
"dev": true,
"dependencies": {
- "is-callable": "^1.1.4",
- "is-date-object": "^1.0.1",
- "is-symbol": "^1.0.2"
+ "@types/normalize-package-data": "^2.4.3",
+ "normalize-package-data": "^6.0.0",
+ "parse-json": "^8.0.0",
+ "type-fest": "^4.6.0",
+ "unicorn-magic": "^0.1.0"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">=18"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/escalade": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "node_modules/@semantic-release/npm/node_modules/semver": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
"dev": true,
- "peer": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
"engines": {
- "node": ">=6"
+ "node": ">=10"
}
},
- "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/@semantic-release/npm/node_modules/type-fest": {
+ "version": "4.18.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.18.2.tgz",
+ "integrity": "sha512-+suCYpfJLAe4OXS6+PPXjW3urOS4IoP9waSiLuXfLgqZODKw/aWwASvzqE886wA0kQgGy0mIWyhd87VpqIy6Xg==",
"dev": true,
"engines": {
- "node": ">=10"
+ "node": ">=16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/eslint": {
- "version": "8.48.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz",
- "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==",
+ "node_modules/@semantic-release/release-notes-generator": {
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-13.0.0.tgz",
+ "integrity": "sha512-LEeZWb340keMYuREMyxrODPXJJ0JOL8D/mCl74B4LdzbxhtXV2LrPN2QBEcGJrlQhoqLO0RhxQb6masHytKw+A==",
"dev": true,
"dependencies": {
- "@eslint-community/eslint-utils": "^4.2.0",
- "@eslint-community/regexpp": "^4.6.1",
- "@eslint/eslintrc": "^2.1.2",
- "@eslint/js": "8.48.0",
- "@humanwhocodes/config-array": "^0.11.10",
- "@humanwhocodes/module-importer": "^1.0.1",
- "@nodelib/fs.walk": "^1.2.8",
- "ajv": "^6.12.4",
- "chalk": "^4.0.0",
- "cross-spawn": "^7.0.2",
- "debug": "^4.3.2",
- "doctrine": "^3.0.0",
- "escape-string-regexp": "^4.0.0",
- "eslint-scope": "^7.2.2",
- "eslint-visitor-keys": "^3.4.3",
- "espree": "^9.6.1",
- "esquery": "^1.4.2",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^6.0.1",
- "find-up": "^5.0.0",
- "glob-parent": "^6.0.2",
- "globals": "^13.19.0",
- "graphemer": "^1.4.0",
- "ignore": "^5.2.0",
- "imurmurhash": "^0.1.4",
- "is-glob": "^4.0.0",
- "is-path-inside": "^3.0.3",
- "js-yaml": "^4.1.0",
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "levn": "^0.4.1",
- "lodash.merge": "^4.6.2",
- "minimatch": "^3.1.2",
- "natural-compare": "^1.4.0",
- "optionator": "^0.9.3",
- "strip-ansi": "^6.0.1",
- "text-table": "^0.2.0"
+ "conventional-changelog-angular": "^7.0.0",
+ "conventional-changelog-writer": "^7.0.0",
+ "conventional-commits-filter": "^4.0.0",
+ "conventional-commits-parser": "^5.0.0",
+ "debug": "^4.0.0",
+ "get-stream": "^7.0.0",
+ "import-from-esm": "^1.0.3",
+ "into-stream": "^7.0.0",
+ "lodash-es": "^4.17.21",
+ "read-pkg-up": "^11.0.0"
},
- "bin": {
- "eslint": "bin/eslint.js"
+ "engines": {
+ "node": ">=20.8.1"
},
+ "peerDependencies": {
+ "semantic-release": ">=20.1.0"
+ }
+ },
+ "node_modules/@semantic-release/release-notes-generator/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,
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": ">=16"
},
"funding": {
- "url": "https://opencollective.com/eslint"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/eslint-config-airbnb-base": {
- "version": "15.0.0",
- "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz",
- "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==",
+ "node_modules/@semantic-release/release-notes-generator/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,
"dependencies": {
- "confusing-browser-globals": "^1.0.10",
- "object.assign": "^4.1.2",
- "object.entries": "^1.1.5",
- "semver": "^6.3.0"
+ "lru-cache": "^10.0.1"
},
"engines": {
- "node": "^10.12.0 || >=12.0.0"
- },
- "peerDependencies": {
- "eslint": "^7.32.0 || ^8.2.0",
- "eslint-plugin-import": "^2.25.2"
+ "node": "^16.14.0 || >=18.0.0"
}
},
- "node_modules/eslint-import-resolver-node": {
- "version": "0.3.9",
- "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
- "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
+ "node_modules/@semantic-release/release-notes-generator/node_modules/lru-cache": {
+ "version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz",
+ "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==",
"dev": true,
- "dependencies": {
- "debug": "^3.2.7",
- "is-core-module": "^2.13.0",
- "resolve": "^1.22.4"
+ "engines": {
+ "node": "14 || >=16.14"
}
},
- "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==",
+ "node_modules/@semantic-release/release-notes-generator/node_modules/normalize-package-data": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.1.tgz",
+ "integrity": "sha512-6rvCfeRW+OEZagAB4lMLSNuTNYZWLVtKccK79VSTf//yTY5VOCgcpH80O+bZK8Neps7pUnd5G+QlMg1yV/2iZQ==",
"dev": true,
"dependencies": {
- "ms": "^2.1.1"
+ "hosted-git-info": "^7.0.0",
+ "is-core-module": "^2.8.1",
+ "semver": "^7.3.5",
+ "validate-npm-package-license": "^3.0.4"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
}
},
- "node_modules/eslint-module-utils": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz",
- "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==",
+ "node_modules/@semantic-release/release-notes-generator/node_modules/parse-json": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz",
+ "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==",
"dev": true,
"dependencies": {
- "debug": "^3.2.7"
+ "@babel/code-frame": "^7.22.13",
+ "index-to-position": "^0.1.2",
+ "type-fest": "^4.7.1"
},
"engines": {
- "node": ">=4"
+ "node": ">=18"
},
- "peerDependenciesMeta": {
- "eslint": {
- "optional": true
- }
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "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==",
+ "node_modules/@semantic-release/release-notes-generator/node_modules/read-pkg": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz",
+ "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==",
"dev": true,
"dependencies": {
- "ms": "^2.1.1"
+ "@types/normalize-package-data": "^2.4.3",
+ "normalize-package-data": "^6.0.0",
+ "parse-json": "^8.0.0",
+ "type-fest": "^4.6.0",
+ "unicorn-magic": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/eslint-plugin-import": {
- "version": "2.28.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz",
- "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==",
+ "node_modules/@semantic-release/release-notes-generator/node_modules/read-pkg-up": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-11.0.0.tgz",
+ "integrity": "sha512-LOVbvF1Q0SZdjClSefZ0Nz5z8u+tIE7mV5NibzmE9VYmDe9CaBbAVtz1veOSZbofrdsilxuDAYnFenukZVp8/Q==",
+ "deprecated": "Renamed to read-package-up",
"dev": true,
"dependencies": {
- "array-includes": "^3.1.6",
- "array.prototype.findlastindex": "^1.2.2",
- "array.prototype.flat": "^1.3.1",
- "array.prototype.flatmap": "^1.3.1",
- "debug": "^3.2.7",
- "doctrine": "^2.1.0",
- "eslint-import-resolver-node": "^0.3.7",
- "eslint-module-utils": "^2.8.0",
- "has": "^1.0.3",
- "is-core-module": "^2.13.0",
- "is-glob": "^4.0.3",
- "minimatch": "^3.1.2",
- "object.fromentries": "^2.0.6",
- "object.groupby": "^1.0.0",
- "object.values": "^1.1.6",
- "semver": "^6.3.1",
- "tsconfig-paths": "^3.14.2"
+ "find-up-simple": "^1.0.0",
+ "read-pkg": "^9.0.0",
+ "type-fest": "^4.6.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=18"
},
- "peerDependencies": {
- "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8"
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "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==",
+ "node_modules/@semantic-release/release-notes-generator/node_modules/semver": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
"dev": true,
- "dependencies": {
- "ms": "^2.1.1"
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
}
},
- "node_modules/eslint-plugin-import/node_modules/doctrine": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
- "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "node_modules/@semantic-release/release-notes-generator/node_modules/type-fest": {
+ "version": "4.18.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.18.2.tgz",
+ "integrity": "sha512-+suCYpfJLAe4OXS6+PPXjW3urOS4IoP9waSiLuXfLgqZODKw/aWwASvzqE886wA0kQgGy0mIWyhd87VpqIy6Xg==",
"dev": true,
- "dependencies": {
- "esutils": "^2.0.2"
- },
"engines": {
- "node": ">=0.10.0"
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/eslint-scope": {
- "version": "7.2.2",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
- "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "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,
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- },
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": ">=10"
},
"funding": {
- "url": "https://opencollective.com/eslint"
+ "url": "https://github.com/sindresorhus/is?sponsor=1"
}
},
- "node_modules/eslint-visitor-keys": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
- "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "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==",
"dev": true,
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": ">=18"
},
"funding": {
- "url": "https://opencollective.com/eslint"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/espree": {
- "version": "9.6.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
- "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "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==",
+ "dev": true
+ },
+ "node_modules/@types/minimist": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
+ "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==",
+ "dev": true
+ },
+ "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
+ },
+ "node_modules/acorn": {
+ "version": "8.10.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
+ "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
"dev": true,
- "dependencies": {
- "acorn": "^8.9.0",
- "acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^3.4.1"
+ "bin": {
+ "acorn": "bin/acorn"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
+ "node": ">=0.4.0"
}
},
- "node_modules/esquery": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
- "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
+ "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
"dev": true,
"dependencies": {
- "estraverse": "^5.1.0"
+ "debug": "^4.3.4"
},
"engines": {
- "node": ">=0.10"
+ "node": ">= 14"
}
},
- "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==",
+ "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,
"dependencies": {
- "estraverse": "^5.2.0"
+ "clean-stack": "^5.2.0",
+ "indent-string": "^5.0.0"
},
"engines": {
- "node": ">=4.0"
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
- "engines": {
- "node": ">=4.0"
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
}
},
- "node_modules/esutils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "node_modules/ansi-escapes": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz",
+ "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==",
"dev": true,
"engines": {
- "node": ">=0.10.0"
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true
- },
- "node_modules/fast-glob": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz",
- "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==",
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.4"
- },
"engines": {
- "node": ">=8.6.0"
+ "node": ">=8"
}
},
- "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==",
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"dependencies": {
- "is-glob": "^4.0.1"
+ "color-convert": "^2.0.1"
},
"engines": {
- "node": ">= 6"
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "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==",
+ "node_modules/any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
"dev": true
},
- "node_modules/fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
- "node_modules/fastest-levenshtein": {
- "version": "1.0.16",
- "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
- "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
- "dev": true,
- "engines": {
- "node": ">= 4.9.1"
- }
- },
- "node_modules/fastq": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
- "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
- "dev": true,
- "dependencies": {
- "reusify": "^1.0.4"
- }
+ "node_modules/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
},
- "node_modules/file-entry-cache": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
- "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
+ "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
"dev": true,
"dependencies": {
- "flat-cache": "^3.0.4"
+ "call-bind": "^1.0.5",
+ "is-array-buffer": "^3.0.4"
},
"engines": {
- "node": "^10.12.0 || >=12.0.0"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "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
+ },
+ "node_modules/array-includes": {
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz",
+ "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==",
"dev": true,
"dependencies": {
- "to-regex-range": "^5.0.1"
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "get-intrinsic": "^1.1.3",
+ "is-string": "^1.0.7"
},
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
"engines": {
"node": ">=8"
}
},
- "node_modules/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/array.prototype.findlastindex": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.2.tgz",
+ "integrity": "sha512-tb5thFFlUcp7NdNF6/MpDk/1r/4awWG1FIz3YqDf+/zJSTezBb+/5WViH41obXULHVpDzoiCLpJ/ZO9YbJMsdw==",
"dev": true,
"dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-shim-unscopables": "^1.0.0",
+ "get-intrinsic": "^1.1.3"
},
"engines": {
- "node": ">=10"
+ "node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/flat-cache": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz",
- "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==",
+ "node_modules/array.prototype.flat": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz",
+ "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==",
"dev": true,
"dependencies": {
- "flatted": "^3.2.7",
- "keyv": "^4.5.3",
- "rimraf": "^3.0.2"
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-shim-unscopables": "^1.0.0"
},
"engines": {
- "node": ">=12.0.0"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/flatted": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
- "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
- "dev": true
- },
- "node_modules/for-each": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
- "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "node_modules/array.prototype.flatmap": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz",
+ "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==",
"dev": true,
"dependencies": {
- "is-callable": "^1.1.3"
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-shim-unscopables": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "dev": true
- },
- "node_modules/function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
- "dev": true
- },
- "node_modules/function.prototype.name": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz",
- "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==",
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz",
+ "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "functions-have-names": "^1.2.3"
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.5",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.22.3",
+ "es-errors": "^1.2.1",
+ "get-intrinsic": "^1.2.3",
+ "is-array-buffer": "^3.0.4",
+ "is-shared-array-buffer": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -2018,48 +1903,40 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "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==",
+ "node_modules/arrify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+ "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
"dev": true,
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "engines": {
+ "node": ">=0.10.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/astral-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
"dev": true,
- "peer": true,
"engines": {
- "node": ">=6.9.0"
+ "node": ">=8"
}
},
- "node_modules/get-intrinsic": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
- "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
+ "node_modules/async": {
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
+ "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
"dev": true,
"dependencies": {
- "function-bind": "^1.1.1",
- "has": "^1.0.3",
- "has-proto": "^1.0.1",
- "has-symbols": "^1.0.3"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "lodash": "^4.17.14"
}
},
- "node_modules/get-symbol-description": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
- "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "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==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.1"
+ "possible-typed-array-names": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -2068,119 +1945,124 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
},
- "node_modules/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==",
+ "node_modules/basic-auth": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
+ "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
"dev": true,
"dependencies": {
- "is-glob": "^4.0.3"
+ "safe-buffer": "5.1.2"
},
"engines": {
- "node": ">=10.13.0"
+ "node": ">= 0.8"
}
},
- "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==",
+ "node_modules/before-after-hook": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz",
+ "integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==",
+ "dev": true
+ },
+ "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
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
- "global-prefix": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
}
},
- "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==",
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"dependencies": {
- "ini": "^1.3.5",
- "kind-of": "^6.0.2",
- "which": "^1.3.1"
+ "fill-range": "^7.0.1"
},
"engines": {
- "node": ">=6"
+ "node": ">=8"
}
},
- "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==",
+ "node_modules/browserslist": {
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
+ "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
"dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "peer": true,
"dependencies": {
- "isexe": "^2.0.0"
+ "caniuse-lite": "^1.0.30001541",
+ "electron-to-chromium": "^1.4.535",
+ "node-releases": "^2.0.13",
+ "update-browserslist-db": "^1.0.13"
},
"bin": {
- "which": "bin/which"
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
- "node_modules/globals": {
- "version": "13.21.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz",
- "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==",
+ "node_modules/call-bind": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
+ "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"dev": true,
"dependencies": {
- "type-fest": "^0.20.2"
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.1"
},
"engines": {
- "node": ">=8"
+ "node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/globalthis": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
- "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true,
- "dependencies": {
- "define-properties": "^1.1.3"
- },
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">=6"
}
},
- "node_modules/globby": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
- "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
"dev": true,
- "dependencies": {
- "array-union": "^2.1.0",
- "dir-glob": "^3.0.1",
- "fast-glob": "^3.2.9",
- "ignore": "^5.2.0",
- "merge2": "^1.4.1",
- "slash": "^3.0.0"
- },
"engines": {
"node": ">=10"
},
@@ -2188,450 +2070,481 @@
"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==",
- "dev": true
- },
- "node_modules/gopd": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
- "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+ "node_modules/camelcase-keys": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz",
+ "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==",
"dev": true,
"dependencies": {
- "get-intrinsic": "^1.1.3"
+ "camelcase": "^6.3.0",
+ "map-obj": "^4.1.0",
+ "quick-lru": "^5.1.1",
+ "type-fest": "^1.2.1"
+ },
+ "engines": {
+ "node": ">=12"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/graphemer": {
+ "node_modules/camelcase-keys/node_modules/type-fest": {
"version": "1.4.0",
- "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
- "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
- "dev": true
- },
- "node_modules/hard-rejection": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
- "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
+ "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==",
"dev": true,
"engines": {
- "node": ">=6"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001543",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001543.tgz",
+ "integrity": "sha512-qxdO8KPWPQ+Zk6bvNpPeQIOH47qZSYdFZd6dXQzb2KzhnSXju4Kd7H1PkSJx6NICSMgo/IhRZRhhfPTHYpJUCA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "peer": true
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"dependencies": {
- "function-bind": "^1.1.1"
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
},
"engines": {
- "node": ">= 0.4.0"
- }
- },
- "node_modules/has-bigints": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
- "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
- "dev": true,
+ "node": ">=10"
+ },
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "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/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==",
"dev": true,
"engines": {
- "node": ">=8"
+ "node": ">=10"
}
},
- "node_modules/has-property-descriptors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
- "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+ "node_modules/clean-stack": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz",
+ "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==",
"dev": true,
"dependencies": {
- "get-intrinsic": "^1.1.1"
+ "escape-string-regexp": "5.0.0"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
- "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
- "dev": true,
"engines": {
- "node": ">= 0.4"
+ "node": ">=14.16"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/has-symbols": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
- "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "node_modules/clean-stack/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,
"engines": {
- "node": ">= 0.4"
+ "node": ">=12"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/has-tostringtag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
- "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "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,
"dependencies": {
- "has-symbols": "^1.0.2"
+ "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"
},
- "engines": {
- "node": ">= 0.4"
+ "bin": {
+ "highlight": "bin/highlight"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "engines": {
+ "node": ">=8.0.0",
+ "npm": ">=5.0.0"
}
},
- "node_modules/hosted-git-info": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
- "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
+ "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,
"dependencies": {
- "lru-cache": "^6.0.0"
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "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,
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
},
"engines": {
"node": ">=10"
}
},
- "node_modules/html-tags": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz",
- "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==",
+ "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,
+ "dependencies": {
+ "string-width": "^4.2.0"
+ },
"engines": {
- "node": ">=8"
+ "node": "10.* || >= 12.*"
},
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "optionalDependencies": {
+ "@colors/colors": "1.5.0"
}
},
- "node_modules/ignore": {
- "version": "5.2.4",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
- "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
"engines": {
- "node": ">= 4"
+ "node": ">=12"
}
},
- "node_modules/import-fresh": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
- "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"dependencies": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
+ "color-name": "~1.1.4"
},
"engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": ">=7.0.0"
}
},
- "node_modules/import-lazy": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
- "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/colord": {
+ "version": "2.9.3",
+ "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
+ "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
+ "dev": true
+ },
+ "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,
- "engines": {
- "node": ">=8"
+ "dependencies": {
+ "array-ify": "^1.0.0",
+ "dot-prop": "^5.1.0"
}
},
- "node_modules/imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true
+ },
+ "node_modules/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,
- "engines": {
- "node": ">=0.8.19"
+ "dependencies": {
+ "ini": "^1.3.4",
+ "proto-list": "~1.2.1"
}
},
- "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==",
+ "node_modules/confusing-browser-globals": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz",
+ "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==",
+ "dev": true
+ },
+ "node_modules/console-grid": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/console-grid/-/console-grid-2.2.2.tgz",
+ "integrity": "sha512-ohlgXexdDTKLNsZz7DSJuCAwmRc8omSS61txOk39W3NOthgKGr1a1jJpZ5BCQe4PlrwMw01OvPQ1Bl3G7Y/uFg==",
+ "dev": true
+ },
+ "node_modules/conventional-changelog-angular": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz",
+ "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==",
"dev": true,
- "engines": {
- "node": ">=12"
+ "dependencies": {
+ "compare-func": "^2.0.0"
},
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "engines": {
+ "node": ">=16"
}
},
- "node_modules/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "dev": true,
- "dependencies": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true
- },
- "node_modules/ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
- "dev": true
- },
- "node_modules/internal-slot": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz",
- "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==",
+ "node_modules/conventional-changelog-writer": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-7.0.1.tgz",
+ "integrity": "sha512-Uo+R9neH3r/foIvQ0MKcsXkX642hdm9odUp7TqgFS7BsalTcjzRlIfWZrZR1gbxOozKucaKt5KAbjW8J8xRSmA==",
"dev": true,
"dependencies": {
- "get-intrinsic": "^1.2.0",
- "has": "^1.0.3",
- "side-channel": "^1.0.4"
+ "conventional-commits-filter": "^4.0.0",
+ "handlebars": "^4.7.7",
+ "json-stringify-safe": "^5.0.1",
+ "meow": "^12.0.1",
+ "semver": "^7.5.2",
+ "split2": "^4.0.0"
+ },
+ "bin": {
+ "conventional-changelog-writer": "cli.mjs"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">=16"
}
},
- "node_modules/is-array-buffer": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
- "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==",
+ "node_modules/conventional-changelog-writer/node_modules/meow": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+ "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
"dev": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.2.0",
- "is-typed-array": "^1.1.10"
+ "engines": {
+ "node": ">=16.10"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/is-arrayish": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
- "dev": true
- },
- "node_modules/is-bigint": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
- "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "node_modules/conventional-changelog-writer/node_modules/semver": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
"dev": true,
- "dependencies": {
- "has-bigints": "^1.0.1"
+ "bin": {
+ "semver": "bin/semver.js"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "engines": {
+ "node": ">=10"
}
},
- "node_modules/is-boolean-object": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
- "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "node_modules/conventional-commits-filter": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-4.0.0.tgz",
+ "integrity": "sha512-rnpnibcSOdFcdclpFwWa+pPlZJhXE7l+XK04zxhbWrhgpR96h33QLz8hITTXbcYICxVr3HZFtbtUAQ+4LdBo9A==",
"dev": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
- },
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">=16"
}
},
- "node_modules/is-callable": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
- "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "node_modules/conventional-commits-parser": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz",
+ "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==",
"dev": true,
- "engines": {
- "node": ">= 0.4"
+ "dependencies": {
+ "is-text-path": "^2.0.0",
+ "JSONStream": "^1.3.5",
+ "meow": "^12.0.1",
+ "split2": "^4.0.0"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "bin": {
+ "conventional-commits-parser": "cli.mjs"
+ },
+ "engines": {
+ "node": ">=16"
}
},
- "node_modules/is-core-module": {
- "version": "2.13.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz",
- "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==",
+ "node_modules/conventional-commits-parser/node_modules/meow": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+ "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
"dev": true,
- "dependencies": {
- "has": "^1.0.3"
+ "engines": {
+ "node": ">=16.10"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/is-date-object": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
- "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "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,
- "dependencies": {
- "has-tostringtag": "^1.0.0"
- },
"engines": {
- "node": ">= 0.4"
+ "node": ">=12"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
+ "peer": true
},
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "dev": true
+ },
+ "node_modules/corser": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz",
+ "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==",
"dev": true,
"engines": {
- "node": ">=8"
+ "node": ">= 0.4.0"
}
},
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "node_modules/cosmiconfig": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz",
+ "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==",
"dev": true,
"dependencies": {
- "is-extglob": "^2.1.1"
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "parse-json": "^5.0.0",
+ "path-type": "^4.0.0"
},
"engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-negative-zero": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
- "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
- "dev": true,
- "engines": {
- "node": ">= 0.4"
+ "node": ">=14"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/d-fischer"
}
},
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
"engines": {
- "node": ">=0.12.0"
+ "node": ">= 8"
}
},
- "node_modules/is-number-object": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
- "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+ "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==",
"dev": true,
"dependencies": {
- "has-tostringtag": "^1.0.0"
+ "type-fest": "^1.0.1"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">=12"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-path-inside": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
- "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "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/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==",
"dev": true,
"engines": {
- "node": ">=0.10.0"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/is-plain-object": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
- "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "node_modules/css-functions-list": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.0.tgz",
+ "integrity": "sha512-d/jBMPyYybkkLVypgtGv12R+pIFw4/f/IHtCTxWpZc8ofTYOPigIgmA6vu5rMHartZC+WuXhBUHfnyNUIQSYrg==",
"dev": true,
"engines": {
- "node": ">=0.10.0"
+ "node": ">=12.22"
}
},
- "node_modules/is-regex": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
- "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "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==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
+ "mdn-data": "2.0.30",
+ "source-map-js": "^1.0.1"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
}
},
- "node_modules/is-shared-array-buffer": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
- "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"dev": true,
- "dependencies": {
- "call-bind": "^1.0.2"
+ "bin": {
+ "cssesc": "bin/cssesc"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "engines": {
+ "node": ">=4"
}
},
- "node_modules/is-string": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
- "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "node_modules/data-view-buffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
+ "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==",
"dev": true,
"dependencies": {
- "has-tostringtag": "^1.0.0"
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
@@ -2640,13 +2553,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-symbol": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
- "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz",
+ "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==",
"dev": true,
"dependencies": {
- "has-symbols": "^1.0.2"
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
@@ -2655,13 +2570,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-typed-array": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
- "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz",
+ "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==",
"dev": true,
"dependencies": {
- "which-typed-array": "^1.1.11"
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
@@ -2670,391 +2587,5250 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-weakref": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
- "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2"
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decamelize": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz",
+ "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/isarray": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
- "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
- "dev": true
+ "node_modules/decamelize-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
+ "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
+ "dev": true,
+ "dependencies": {
+ "decamelize": "^1.1.0",
+ "map-obj": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
},
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true
+ "node_modules/decamelize-keys/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,
+ "engines": {
+ "node": ">=0.10.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==",
+ "node_modules/decamelize-keys/node_modules/map-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+ "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
"dev": true
},
- "node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dev": true,
"dependencies": {
- "argparse": "^2.0.1"
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
},
- "bin": {
- "js-yaml": "bin/js-yaml.js"
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/jsesc": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
- "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"dev": true,
- "peer": true,
- "bin": {
- "jsesc": "bin/jsesc"
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
},
"engines": {
- "node": ">=4"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/json-buffer": {
+ "node_modules/dir-glob": {
"version": "3.0.1",
- "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
- "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
- "dev": true
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
},
- "node_modules/json-parse-even-better-errors": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
- "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "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,
+ "dependencies": {
+ "is-obj": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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,
+ "dependencies": {
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "node_modules/eight-colors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/eight-colors/-/eight-colors-1.3.0.tgz",
+ "integrity": "sha512-hVoK898cR71ADj7L1LZWaECLaSkzzPtqGXIaKv4K6Pzb72QgjLVsQaNI+ELDQQshzFvgp5xTPkaYkPGqw3YR+g==",
"dev": true
},
- "node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.539",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.539.tgz",
+ "integrity": "sha512-wRmWJ8F7rgmINuI32S6r2SLrw/h/bJQsDSvBiq9GBfvc2Lh73qTOwn73r3Cf67mjVgFGJYcYtmERzySa5jIWlg==",
+ "dev": true,
+ "peer": true
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
- "node_modules/json-stable-stringify-without-jsonify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
- "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "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
},
- "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==",
+ "node_modules/env-ci": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-11.0.0.tgz",
+ "integrity": "sha512-apikxMgkipkgTvMdRT9MNqWx5VLOci79F4VBd7Op/7OPjjoanjdAvn6fglMCCEf/1bAh8eOiuEVCUs4V3qP3nQ==",
"dev": true,
"dependencies": {
- "minimist": "^1.2.0"
+ "execa": "^8.0.0",
+ "java-properties": "^1.0.2"
},
- "bin": {
- "json5": "lib/cli.js"
+ "engines": {
+ "node": "^18.17 || >=20.6.1"
}
},
- "node_modules/keyv": {
- "version": "4.5.3",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz",
- "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==",
+ "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,
"dependencies": {
- "json-buffer": "3.0.1"
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^8.0.1",
+ "human-signals": "^5.0.0",
+ "is-stream": "^3.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^5.1.0",
+ "onetime": "^6.0.0",
+ "signal-exit": "^4.1.0",
+ "strip-final-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.17"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
- "node_modules/kind-of": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
- "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "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,
"engines": {
- "node": ">=0.10.0"
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/known-css-properties": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.28.0.tgz",
- "integrity": "sha512-9pSL5XB4J+ifHP0e0jmmC98OGC1nL8/JjS+fi6mnTlIf//yt/MfVLtKg7S6nCtj/8KTcWX7nRlY0XywoYY1ISQ==",
- "dev": true
- },
- "node_modules/levn": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
- "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "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,
- "dependencies": {
- "prelude-ls": "^1.2.1",
- "type-check": "~0.4.0"
- },
"engines": {
- "node": ">= 0.8.0"
+ "node": ">=16.17.0"
}
},
- "node_modules/lines-and-columns": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
- "dev": true
- },
- "node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "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,
- "dependencies": {
- "p-locate": "^5.0.0"
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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,
"engines": {
- "node": ">=10"
+ "node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/lodash.merge": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
- "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
- "dev": true
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
},
- "node_modules/lodash.truncate": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
- "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
- "dev": true
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.23.3",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz",
+ "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==",
+ "dev": true,
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "arraybuffer.prototype.slice": "^1.0.3",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "data-view-buffer": "^1.0.1",
+ "data-view-byte-length": "^1.0.1",
+ "data-view-byte-offset": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-set-tostringtag": "^2.0.3",
+ "es-to-primitive": "^1.2.1",
+ "function.prototype.name": "^1.1.6",
+ "get-intrinsic": "^1.2.4",
+ "get-symbol-description": "^1.0.2",
+ "globalthis": "^1.0.3",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.0.3",
+ "has-symbols": "^1.0.3",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.0.7",
+ "is-array-buffer": "^3.0.4",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.1",
+ "is-negative-zero": "^2.0.3",
+ "is-regex": "^1.1.4",
+ "is-shared-array-buffer": "^1.0.3",
+ "is-string": "^1.0.7",
+ "is-typed-array": "^1.1.13",
+ "is-weakref": "^1.0.2",
+ "object-inspect": "^1.13.1",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.5",
+ "regexp.prototype.flags": "^1.5.2",
+ "safe-array-concat": "^1.1.2",
+ "safe-regex-test": "^1.0.3",
+ "string.prototype.trim": "^1.2.9",
+ "string.prototype.trimend": "^1.0.8",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.2",
+ "typed-array-byte-length": "^1.0.1",
+ "typed-array-byte-offset": "^1.0.2",
+ "typed-array-length": "^1.0.6",
+ "unbox-primitive": "^1.0.2",
+ "which-typed-array": "^1.1.15"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
+ "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.2.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
+ "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
+ "dev": true,
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
+ "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.2.4",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-shim-unscopables": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz",
+ "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dev": true,
+ "dependencies": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.48.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz",
+ "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.2",
+ "@eslint/js": "8.48.0",
+ "@humanwhocodes/config-array": "^0.11.10",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-config-airbnb-base": {
+ "version": "15.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz",
+ "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==",
+ "dev": true,
+ "dependencies": {
+ "confusing-browser-globals": "^1.0.10",
+ "object.assign": "^4.1.2",
+ "object.entries": "^1.1.5",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^7.32.0 || ^8.2.0",
+ "eslint-plugin-import": "^2.25.2"
+ }
+ },
+ "node_modules/eslint-import-resolver-node": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
+ "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^3.2.7",
+ "is-core-module": "^2.13.0",
+ "resolve": "^1.22.4"
+ }
+ },
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-module-utils": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz",
+ "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^3.2.7"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
+ }
+ },
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-import": {
+ "version": "2.28.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz",
+ "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==",
+ "dev": true,
+ "dependencies": {
+ "array-includes": "^3.1.6",
+ "array.prototype.findlastindex": "^1.2.2",
+ "array.prototype.flat": "^1.3.1",
+ "array.prototype.flatmap": "^1.3.1",
+ "debug": "^3.2.7",
+ "doctrine": "^2.1.0",
+ "eslint-import-resolver-node": "^0.3.7",
+ "eslint-module-utils": "^2.8.0",
+ "has": "^1.0.3",
+ "is-core-module": "^2.13.0",
+ "is-glob": "^4.0.3",
+ "minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.6",
+ "object.groupby": "^1.0.0",
+ "object.values": "^1.1.6",
+ "semver": "^6.3.1",
+ "tsconfig-paths": "^3.14.2"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8"
+ }
+ },
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+ "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eventemitter3": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+ "dev": true
+ },
+ "node_modules/execa": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-9.1.0.tgz",
+ "integrity": "sha512-lSgHc4Elo2m6bUDhc3Hl/VxvUDJdQWI40RZ4KMY9bKRc+hgMOT7II/JjbNDhI8VnMtrCb7U/fhpJIkLORZozWw==",
+ "dev": true,
+ "dependencies": {
+ "@sindresorhus/merge-streams": "^4.0.0",
+ "cross-spawn": "^7.0.3",
+ "figures": "^6.1.0",
+ "get-stream": "^9.0.0",
+ "human-signals": "^7.0.0",
+ "is-plain-obj": "^4.1.0",
+ "is-stream": "^4.0.1",
+ "npm-run-path": "^5.2.0",
+ "pretty-ms": "^9.0.0",
+ "signal-exit": "^4.1.0",
+ "strip-final-newline": "^4.0.0",
+ "yoctocolors": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/execa/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,
+ "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/execa/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,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
+ "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true
+ },
+ "node_modules/fastest-levenshtein": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4.9.1"
+ }
+ },
+ "node_modules/fastq": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
+ "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
+ "dev": true,
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/figures": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz",
+ "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==",
+ "dev": true,
+ "dependencies": {
+ "is-unicode-supported": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/find-up-simple": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz",
+ "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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,
+ "dependencies": {
+ "semver-regex": "^4.0.5",
+ "super-regex": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz",
+ "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==",
+ "dev": true,
+ "dependencies": {
+ "flatted": "^3.2.7",
+ "keyv": "^4.5.3",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
+ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
+ "dev": true
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.6",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
+ "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/for-each": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+ "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "dev": true,
+ "dependencies": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "node_modules/from2": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+ "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==",
+ "dev": true,
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.0"
+ }
+ },
+ "node_modules/fs-extra": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
+ "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/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,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz",
+ "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "functions-have-names": "^1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
+ "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
+ "dev": true,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3",
+ "hasown": "^2.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
+ "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/git-log-parser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz",
+ "integrity": "sha512-rnCVNfkTL8tdNryFuaY0fYiBWEBcgF748O6ZI61rslBvr2o7U65c2/6npCRqH40vuAhtgtDiqLTJjBVdrejCzA==",
+ "dev": true,
+ "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.6"
+ }
+ },
+ "node_modules/git-log-parser/node_modules/split2": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz",
+ "integrity": "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==",
+ "dev": true,
+ "dependencies": {
+ "through2": "~2.0.0"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/global-modules": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
+ "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
+ "dev": true,
+ "dependencies": {
+ "global-prefix": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "ini": "^1.3.5",
+ "kind-of": "^6.0.2",
+ "which": "^1.3.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/global-prefix/node_modules/which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "which": "bin/which"
+ }
+ },
+ "node_modules/globals": {
+ "version": "13.21.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz",
+ "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
+ "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globjoin": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz",
+ "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==",
+ "dev": true
+ },
+ "node_modules/gopd": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+ "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true
+ },
+ "node_modules/handlebars": {
+ "version": "4.7.8",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
+ "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
+ "dev": true,
+ "dependencies": {
+ "minimist": "^1.2.5",
+ "neo-async": "^2.6.2",
+ "source-map": "^0.6.1",
+ "wordwrap": "^1.0.0"
+ },
+ "bin": {
+ "handlebars": "bin/handlebars"
+ },
+ "engines": {
+ "node": ">=0.4.7"
+ },
+ "optionalDependencies": {
+ "uglify-js": "^3.1.4"
+ }
+ },
+ "node_modules/hard-rejection": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
+ "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-bigints": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dev": true,
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
+ "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true,
+ "bin": {
+ "he": "bin/he"
+ }
+ },
+ "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,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/hook-std": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-3.0.0.tgz",
+ "integrity": "sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/hosted-git-info": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+ "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/html-encoding-sniffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
+ "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
+ "dev": true,
+ "dependencies": {
+ "whatwg-encoding": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
+ "node_modules/html-tags": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz",
+ "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/http-proxy": {
+ "version": "1.18.1",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
+ "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+ "dev": true,
+ "dependencies": {
+ "eventemitter3": "^4.0.0",
+ "follow-redirects": "^1.0.0",
+ "requires-port": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/http-server": {
+ "version": "14.1.1",
+ "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz",
+ "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==",
+ "dev": true,
+ "dependencies": {
+ "basic-auth": "^2.0.1",
+ "chalk": "^4.1.2",
+ "corser": "^2.0.1",
+ "he": "^1.2.0",
+ "html-encoding-sniffer": "^3.0.0",
+ "http-proxy": "^1.18.1",
+ "mime": "^1.6.0",
+ "minimist": "^1.2.6",
+ "opener": "^1.5.1",
+ "portfinder": "^1.0.28",
+ "secure-compare": "3.0.1",
+ "union": "~0.5.0",
+ "url-join": "^4.0.1"
+ },
+ "bin": {
+ "http-server": "bin/http-server"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/http-server/node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "dev": true,
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/http-server/node_modules/url-join": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
+ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
+ "dev": true
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz",
+ "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "^7.0.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-7.0.0.tgz",
+ "integrity": "sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/import-from-esm": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-1.3.4.tgz",
+ "integrity": "sha512-7EyUlPFC0HOlBDpUFGfYstsU7XHxZJKAAMzCT8wZ0hMW7b+hG51LIKTDcsgtz8Pu6YC0HqRVbX+rVUtsGMUKvg==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.3.4",
+ "import-meta-resolve": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.20"
+ }
+ },
+ "node_modules/import-lazy": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
+ "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/import-meta-resolve": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz",
+ "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==",
+ "dev": true,
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/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,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/index-to-position": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-0.1.2.tgz",
+ "integrity": "sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true
+ },
+ "node_modules/internal-slot": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
+ "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==",
+ "dev": true,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.0",
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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,
+ "dependencies": {
+ "from2": "^2.3.0",
+ "p-is-promise": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
+ "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true
+ },
+ "node_modules/is-bigint": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+ "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "dev": true,
+ "dependencies": {
+ "has-bigints": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+ "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "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",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.13.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz",
+ "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-view": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz",
+ "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==",
+ "dev": true,
+ "dependencies": {
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+ "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+ "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+ "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+ "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+ "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-text-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz",
+ "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==",
+ "dev": true,
+ "dependencies": {
+ "text-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz",
+ "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==",
+ "dev": true,
+ "dependencies": {
+ "which-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz",
+ "integrity": "sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+ "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "node_modules/issue-parser": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-7.0.0.tgz",
+ "integrity": "sha512-jgAw78HO3gs9UrKqJNQvfDj9Ouy8Mhu40fbEJ8yXff4MW8+/Fcn9iFjyWUQ6SKbX8ipPk3X5A3AyfYHRu6uVLw==",
+ "dev": true,
+ "dependencies": {
+ "lodash.capitalize": "^4.2.1",
+ "lodash.escaperegexp": "^4.1.2",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.isstring": "^4.0.1",
+ "lodash.uniqby": "^4.7.0"
+ },
+ "engines": {
+ "node": "^18.17 || >=20.6.1"
+ }
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
+ "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
+ "dev": true,
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/java-properties": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz",
+ "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true,
+ "peer": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true
+ },
+ "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",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true
+ },
+ "node_modules/json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
+ "dev": true
+ },
+ "node_modules/json5": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+ "dev": true,
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
+ "node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/jsonparse": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
+ "dev": true,
+ "engines": [
+ "node >= 0.2.0"
+ ]
+ },
+ "node_modules/JSONStream": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
+ "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
+ "dev": true,
+ "dependencies": {
+ "jsonparse": "^1.2.0",
+ "through": ">=2.2.7 <3"
+ },
+ "bin": {
+ "JSONStream": "bin.js"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.3",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz",
+ "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==",
+ "dev": true,
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/known-css-properties": {
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.28.0.tgz",
+ "integrity": "sha512-9pSL5XB4J+ifHP0e0jmmC98OGC1nL8/JjS+fi6mnTlIf//yt/MfVLtKg7S6nCtj/8KTcWX7nRlY0XywoYY1ISQ==",
+ "dev": true
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true
+ },
+ "node_modules/load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/load-json-file/node_modules/parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
+ "dev": true,
+ "dependencies": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "node_modules/lodash-es": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+ "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
+ "dev": true
+ },
+ "node_modules/lodash.capitalize": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz",
+ "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==",
+ "dev": true
+ },
+ "node_modules/lodash.escaperegexp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
+ "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==",
+ "dev": true
+ },
+ "node_modules/lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+ "dev": true
+ },
+ "node_modules/lodash.isstring": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+ "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
+ "dev": true
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true
+ },
+ "node_modules/lodash.truncate": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
+ "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
+ "dev": true
+ },
+ "node_modules/lodash.uniqby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz",
+ "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==",
+ "dev": true
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/lz-utils": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lz-utils/-/lz-utils-2.0.2.tgz",
+ "integrity": "sha512-i1PJN4hNEevkrvLMqNWCCac1BcB5SRaghywG7HVzWOyVkFOasLCG19ND1sY1F/ZEsM6SnGtoXyBWnmfqOM5r6g==",
+ "dev": true
+ },
+ "node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/make-dir/node_modules/semver": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/map-obj": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
+ "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/marked": {
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.2.tgz",
+ "integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==",
+ "dev": true,
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/marked-terminal": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.0.0.tgz",
+ "integrity": "sha512-sNEx8nn9Ktcm6pL0TnRz8tnXq/mSS0Q1FRSwJOAqw4lAB4l49UeDf85Gm1n9RPFm5qurCPjwi1StAQT2XExhZw==",
+ "dev": true,
+ "dependencies": {
+ "ansi-escapes": "^6.2.0",
+ "chalk": "^5.3.0",
+ "cli-highlight": "^2.1.11",
+ "cli-table3": "^0.6.3",
+ "node-emoji": "^2.1.3",
+ "supports-hyperlinks": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "peerDependencies": {
+ "marked": ">=1 <13"
+ }
+ },
+ "node_modules/marked-terminal/node_modules/chalk": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+ "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+ "dev": true,
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/mathml-tag-names": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz",
+ "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==",
+ "dev": true,
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "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==",
+ "dev": true
+ },
+ "node_modules/meow": {
+ "version": "10.1.5",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz",
+ "integrity": "sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==",
+ "dev": true,
+ "dependencies": {
+ "@types/minimist": "^1.2.2",
+ "camelcase-keys": "^7.0.0",
+ "decamelize": "^5.0.0",
+ "decamelize-keys": "^1.1.0",
+ "hard-rejection": "^2.1.0",
+ "minimist-options": "4.1.0",
+ "normalize-package-data": "^3.0.2",
+ "read-pkg-up": "^8.0.0",
+ "redent": "^4.0.0",
+ "trim-newlines": "^4.0.2",
+ "type-fest": "^1.2.2",
+ "yargs-parser": "^20.2.9"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/meow/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==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.3.tgz",
+ "integrity": "sha512-KgUb15Oorc0NEKPbvfa0wRU+PItIEZmiv+pyAO2i0oTIVTJhlzMclU7w4RXWQrSOVH5ax/p/CkIO7KI4OyFJTQ==",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/broofa"
+ ],
+ "bin": {
+ "mime": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minimist-options": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
+ "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
+ "dev": true,
+ "dependencies": {
+ "arrify": "^1.0.1",
+ "is-plain-obj": "^1.1.0",
+ "kind-of": "^6.0.3"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+ "dev": true,
+ "dependencies": {
+ "minimist": "^1.2.6"
+ },
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ }
+ },
+ "node_modules/monocart-code-viewer": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/monocart-code-viewer/-/monocart-code-viewer-1.1.3.tgz",
+ "integrity": "sha512-v1dbT8fDr9vjyjEYE035JSC4JXBA/Z034mogVJWRO3khX0/guVwGb69iSIYSzTbR9+KpRKV/C/AscRAkUwP32w==",
+ "dev": true
+ },
+ "node_modules/monocart-coverage-reports": {
+ "version": "2.8.2",
+ "resolved": "https://registry.npmjs.org/monocart-coverage-reports/-/monocart-coverage-reports-2.8.2.tgz",
+ "integrity": "sha512-7PjHQlH47IvF+IVMLvO3dmTEOyiJpRVn67X2NY7gx8qQO0fW+j4cClojQwjcDaV4WWlAnOIsukcODxfxMUlC+Q==",
+ "dev": true,
+ "dependencies": {
+ "console-grid": "^2.2.2",
+ "eight-colors": "^1.3.0",
+ "istanbul-lib-coverage": "^3.2.2",
+ "istanbul-lib-report": "^3.0.1",
+ "istanbul-reports": "^3.1.7",
+ "lz-utils": "^2.0.2",
+ "monocart-code-viewer": "^1.1.3",
+ "monocart-formatter": "^3.0.0",
+ "monocart-locator": "^1.0.0",
+ "turbogrid": "^3.0.13"
+ },
+ "bin": {
+ "mcr": "lib/cli.js"
+ }
+ },
+ "node_modules/monocart-formatter": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/monocart-formatter/-/monocart-formatter-3.0.0.tgz",
+ "integrity": "sha512-91OQpUb/9iDqvrblUv6ki11Jxi1d3Fp5u2jfVAPl3UdNp9TM+iBleLzXntUS51W0o+zoya3CJjZZ01z2XWn25g==",
+ "dev": true
+ },
+ "node_modules/monocart-locator": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/monocart-locator/-/monocart-locator-1.0.0.tgz",
+ "integrity": "sha512-qIHJ7f99miF2HbVUWAFKR93SfgGYpFPUCQPmW9q1VXU9onxMUFJxhQDdG3HkEteogUbsKB7Gr5MRgjzcIxwTaQ==",
+ "dev": true
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "dev": true,
+ "dependencies": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
+ "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true
+ },
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true
+ },
+ "node_modules/nerf-dart": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz",
+ "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==",
+ "dev": true
+ },
+ "node_modules/node-emoji": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz",
+ "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==",
+ "dev": true,
+ "dependencies": {
+ "@sindresorhus/is": "^4.6.0",
+ "char-regex": "^1.0.2",
+ "emojilib": "^2.4.0",
+ "skin-tone": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.13",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
+ "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
+ "dev": true,
+ "peer": true
+ },
+ "node_modules/normalize-package-data": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
+ "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
+ "dev": true,
+ "dependencies": {
+ "hosted-git-info": "^4.0.1",
+ "is-core-module": "^2.5.0",
+ "semver": "^7.3.4",
+ "validate-npm-package-license": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/normalize-package-data/node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-url": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz",
+ "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm": {
+ "version": "10.8.0",
+ "resolved": "https://registry.npmjs.org/npm/-/npm-10.8.0.tgz",
+ "integrity": "sha512-wh93uRczgp7HDnPMiLXcCkv2hagdJS0zJ9KT/31d0FoXP02+qgN2AOwpaW85fxRWkinl2rELfPw+CjBXW48/jQ==",
+ "bundleDependencies": [
+ "@isaacs/string-locale-compare",
+ "@npmcli/arborist",
+ "@npmcli/config",
+ "@npmcli/fs",
+ "@npmcli/map-workspaces",
+ "@npmcli/package-json",
+ "@npmcli/promise-spawn",
+ "@npmcli/redact",
+ "@npmcli/run-script",
+ "@sigstore/tuf",
+ "abbrev",
+ "archy",
+ "cacache",
+ "chalk",
+ "ci-info",
+ "cli-columns",
+ "fastest-levenshtein",
+ "fs-minipass",
+ "glob",
+ "graceful-fs",
+ "hosted-git-info",
+ "ini",
+ "init-package-json",
+ "is-cidr",
+ "json-parse-even-better-errors",
+ "libnpmaccess",
+ "libnpmdiff",
+ "libnpmexec",
+ "libnpmfund",
+ "libnpmhook",
+ "libnpmorg",
+ "libnpmpack",
+ "libnpmpublish",
+ "libnpmsearch",
+ "libnpmteam",
+ "libnpmversion",
+ "make-fetch-happen",
+ "minimatch",
+ "minipass",
+ "minipass-pipeline",
+ "ms",
+ "node-gyp",
+ "nopt",
+ "normalize-package-data",
+ "npm-audit-report",
+ "npm-install-checks",
+ "npm-package-arg",
+ "npm-pick-manifest",
+ "npm-profile",
+ "npm-registry-fetch",
+ "npm-user-validate",
+ "p-map",
+ "pacote",
+ "parse-conflict-json",
+ "proc-log",
+ "qrcode-terminal",
+ "read",
+ "semver",
+ "spdx-expression-parse",
+ "ssri",
+ "supports-color",
+ "tar",
+ "text-table",
+ "tiny-relative-date",
+ "treeverse",
+ "validate-npm-package-name",
+ "which",
+ "write-file-atomic"
+ ],
+ "dependencies": {
+ "@isaacs/string-locale-compare": "^1.1.0",
+ "@npmcli/arborist": "^7.5.2",
+ "@npmcli/config": "^8.3.2",
+ "@npmcli/fs": "^3.1.1",
+ "@npmcli/map-workspaces": "^3.0.6",
+ "@npmcli/package-json": "^5.1.0",
+ "@npmcli/promise-spawn": "^7.0.2",
+ "@npmcli/redact": "^2.0.0",
+ "@npmcli/run-script": "^8.1.0",
+ "@sigstore/tuf": "^2.3.3",
+ "abbrev": "^2.0.0",
+ "archy": "~1.0.0",
+ "cacache": "^18.0.3",
+ "chalk": "^5.3.0",
+ "ci-info": "^4.0.0",
+ "cli-columns": "^4.0.0",
+ "fastest-levenshtein": "^1.0.16",
+ "fs-minipass": "^3.0.3",
+ "glob": "^10.3.15",
+ "graceful-fs": "^4.2.11",
+ "hosted-git-info": "^7.0.2",
+ "ini": "^4.1.2",
+ "init-package-json": "^6.0.3",
+ "is-cidr": "^5.0.5",
+ "json-parse-even-better-errors": "^3.0.2",
+ "libnpmaccess": "^8.0.6",
+ "libnpmdiff": "^6.1.2",
+ "libnpmexec": "^8.1.1",
+ "libnpmfund": "^5.0.10",
+ "libnpmhook": "^10.0.5",
+ "libnpmorg": "^6.0.6",
+ "libnpmpack": "^7.0.2",
+ "libnpmpublish": "^9.0.8",
+ "libnpmsearch": "^7.0.5",
+ "libnpmteam": "^6.0.5",
+ "libnpmversion": "^6.0.2",
+ "make-fetch-happen": "^13.0.1",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.1",
+ "minipass-pipeline": "^1.2.4",
+ "ms": "^2.1.2",
+ "node-gyp": "^10.1.0",
+ "nopt": "^7.2.1",
+ "normalize-package-data": "^6.0.1",
+ "npm-audit-report": "^5.0.0",
+ "npm-install-checks": "^6.3.0",
+ "npm-package-arg": "^11.0.2",
+ "npm-pick-manifest": "^9.0.1",
+ "npm-profile": "^10.0.0",
+ "npm-registry-fetch": "^17.0.1",
+ "npm-user-validate": "^2.0.1",
+ "p-map": "^4.0.0",
+ "pacote": "^18.0.6",
+ "parse-conflict-json": "^3.0.1",
+ "proc-log": "^4.2.0",
+ "qrcode-terminal": "^0.12.0",
+ "read": "^3.0.1",
+ "semver": "^7.6.2",
+ "spdx-expression-parse": "^4.0.0",
+ "ssri": "^10.0.6",
+ "supports-color": "^9.4.0",
+ "tar": "^6.2.1",
+ "text-table": "~0.2.0",
+ "tiny-relative-date": "^1.3.0",
+ "treeverse": "^3.0.0",
+ "validate-npm-package-name": "^5.0.1",
+ "which": "^4.0.0",
+ "write-file-atomic": "^5.0.1"
+ },
+ "bin": {
+ "npm": "bin/npm-cli.js",
+ "npx": "bin/npx-cli.js"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "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,
+ "dependencies": {
+ "path-key": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm-run-path/node_modules/path-key": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm/node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": {
+ "version": "5.1.2",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/@isaacs/string-locale-compare": {
+ "version": "1.1.0",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/@npmcli/agent": {
+ "version": "2.2.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.1",
+ "lru-cache": "^10.0.1",
+ "socks-proxy-agent": "^8.0.3"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/arborist": {
+ "version": "7.5.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@isaacs/string-locale-compare": "^1.1.0",
+ "@npmcli/fs": "^3.1.1",
+ "@npmcli/installed-package-contents": "^2.1.0",
+ "@npmcli/map-workspaces": "^3.0.2",
+ "@npmcli/metavuln-calculator": "^7.1.1",
+ "@npmcli/name-from-folder": "^2.0.0",
+ "@npmcli/node-gyp": "^3.0.0",
+ "@npmcli/package-json": "^5.1.0",
+ "@npmcli/query": "^3.1.0",
+ "@npmcli/redact": "^2.0.0",
+ "@npmcli/run-script": "^8.1.0",
+ "bin-links": "^4.0.4",
+ "cacache": "^18.0.3",
+ "common-ancestor-path": "^1.0.1",
+ "hosted-git-info": "^7.0.2",
+ "json-parse-even-better-errors": "^3.0.2",
+ "json-stringify-nice": "^1.1.4",
+ "lru-cache": "^10.2.2",
+ "minimatch": "^9.0.4",
+ "nopt": "^7.2.1",
+ "npm-install-checks": "^6.2.0",
+ "npm-package-arg": "^11.0.2",
+ "npm-pick-manifest": "^9.0.1",
+ "npm-registry-fetch": "^17.0.1",
+ "pacote": "^18.0.6",
+ "parse-conflict-json": "^3.0.0",
+ "proc-log": "^4.2.0",
+ "proggy": "^2.0.0",
+ "promise-all-reject-late": "^1.0.0",
+ "promise-call-limit": "^3.0.1",
+ "read-package-json-fast": "^3.0.2",
+ "semver": "^7.3.7",
+ "ssri": "^10.0.6",
+ "treeverse": "^3.0.0",
+ "walk-up-path": "^3.0.1"
+ },
+ "bin": {
+ "arborist": "bin/index.js"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/config": {
+ "version": "8.3.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/map-workspaces": "^3.0.2",
+ "ci-info": "^4.0.0",
+ "ini": "^4.1.2",
+ "nopt": "^7.2.1",
+ "proc-log": "^4.2.0",
+ "read-package-json-fast": "^3.0.2",
+ "semver": "^7.3.5",
+ "walk-up-path": "^3.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/fs": {
+ "version": "3.1.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/git": {
+ "version": "5.0.7",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/promise-spawn": "^7.0.0",
+ "lru-cache": "^10.0.1",
+ "npm-pick-manifest": "^9.0.0",
+ "proc-log": "^4.0.0",
+ "promise-inflight": "^1.0.1",
+ "promise-retry": "^2.0.1",
+ "semver": "^7.3.5",
+ "which": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/installed-package-contents": {
+ "version": "2.1.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-bundled": "^3.0.0",
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "bin": {
+ "installed-package-contents": "bin/index.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/map-workspaces": {
+ "version": "3.0.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/name-from-folder": "^2.0.0",
+ "glob": "^10.2.2",
+ "minimatch": "^9.0.0",
+ "read-package-json-fast": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/metavuln-calculator": {
+ "version": "7.1.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "cacache": "^18.0.0",
+ "json-parse-even-better-errors": "^3.0.0",
+ "pacote": "^18.0.0",
+ "proc-log": "^4.1.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/name-from-folder": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/node-gyp": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/package-json": {
+ "version": "5.1.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/git": "^5.0.0",
+ "glob": "^10.2.2",
+ "hosted-git-info": "^7.0.0",
+ "json-parse-even-better-errors": "^3.0.0",
+ "normalize-package-data": "^6.0.0",
+ "proc-log": "^4.0.0",
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/promise-spawn": {
+ "version": "7.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "which": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/query": {
+ "version": "3.1.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.10"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/redact": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/run-script": {
+ "version": "8.1.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/node-gyp": "^3.0.0",
+ "@npmcli/package-json": "^5.0.0",
+ "@npmcli/promise-spawn": "^7.0.0",
+ "node-gyp": "^10.0.0",
+ "proc-log": "^4.0.0",
+ "which": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/npm/node_modules/@sigstore/bundle": {
+ "version": "2.3.1",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@sigstore/protobuf-specs": "^0.3.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@sigstore/core": {
+ "version": "1.1.0",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@sigstore/protobuf-specs": {
+ "version": "0.3.2",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@sigstore/sign": {
+ "version": "2.3.1",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@sigstore/bundle": "^2.3.0",
+ "@sigstore/core": "^1.0.0",
+ "@sigstore/protobuf-specs": "^0.3.1",
+ "make-fetch-happen": "^13.0.1",
+ "proc-log": "^4.2.0",
+ "promise-retry": "^2.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@sigstore/tuf": {
+ "version": "2.3.3",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@sigstore/protobuf-specs": "^0.3.0",
+ "tuf-js": "^2.2.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@sigstore/verify": {
+ "version": "1.2.0",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@sigstore/bundle": "^2.3.1",
+ "@sigstore/core": "^1.1.0",
+ "@sigstore/protobuf-specs": "^0.3.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@tufjs/canonical-json": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@tufjs/models": {
+ "version": "2.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "@tufjs/canonical-json": "2.0.0",
+ "minimatch": "^9.0.4"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/abbrev": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/agent-base": {
+ "version": "7.1.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/npm/node_modules/aggregate-error": {
+ "version": "3.1.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/aproba": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/archy": {
+ "version": "1.0.0",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/bin-links": {
+ "version": "4.0.4",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "cmd-shim": "^6.0.0",
+ "npm-normalize-package-bin": "^3.0.0",
+ "read-cmd-shim": "^4.0.0",
+ "write-file-atomic": "^5.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/cacache": {
+ "version": "18.0.3",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/fs": "^3.1.0",
+ "fs-minipass": "^3.0.0",
+ "glob": "^10.2.2",
+ "lru-cache": "^10.0.1",
+ "minipass": "^7.0.3",
+ "minipass-collect": "^2.0.1",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "p-map": "^4.0.0",
+ "ssri": "^10.0.0",
+ "tar": "^6.1.11",
+ "unique-filename": "^3.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/chalk": {
+ "version": "5.3.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/chownr": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/ci-info": {
+ "version": "4.0.0",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/cidr-regex": {
+ "version": "4.0.5",
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "ip-regex": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/npm/node_modules/clean-stack": {
+ "version": "2.2.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/npm/node_modules/cli-columns": {
+ "version": "4.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "string-width": "^4.2.3",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/npm/node_modules/cmd-shim": {
+ "version": "6.0.3",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/color-convert": {
+ "version": "2.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/color-name": {
+ "version": "1.1.4",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/common-ancestor-path": {
+ "version": "1.0.1",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/npm/node_modules/cross-spawn/node_modules/which": {
+ "version": "2.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/npm/node_modules/cssesc": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/npm/node_modules/debug": {
+ "version": "4.3.4",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/npm/node_modules/debug/node_modules/ms": {
+ "version": "2.1.2",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/diff": {
+ "version": "5.2.0",
+ "inBundle": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/npm/node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/encoding": {
+ "version": "0.1.13",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "^0.6.2"
+ }
+ },
+ "node_modules/npm/node_modules/env-paths": {
+ "version": "2.2.1",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/npm/node_modules/err-code": {
+ "version": "2.0.3",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/exponential-backoff": {
+ "version": "3.1.1",
+ "inBundle": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/npm/node_modules/fastest-levenshtein": {
+ "version": "1.0.16",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.9.1"
+ }
+ },
+ "node_modules/npm/node_modules/foreground-child": {
+ "version": "3.1.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/fs-minipass": {
+ "version": "3.0.3",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/function-bind": {
+ "version": "1.1.2",
+ "inBundle": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/npm/node_modules/glob": {
+ "version": "10.3.15",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^2.3.6",
+ "minimatch": "^9.0.1",
+ "minipass": "^7.0.4",
+ "path-scurry": "^1.11.0"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/hasown": {
+ "version": "2.0.2",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/npm/node_modules/hosted-git-info": {
+ "version": "7.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^10.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/http-cache-semantics": {
+ "version": "4.1.1",
+ "inBundle": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/npm/node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/npm/node_modules/https-proxy-agent": {
+ "version": "7.0.4",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.0.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/npm/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm/node_modules/ignore-walk": {
+ "version": "6.0.5",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minimatch": "^9.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/npm/node_modules/indent-string": {
+ "version": "4.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/ini": {
+ "version": "4.1.2",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/init-package-json": {
+ "version": "6.0.3",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/package-json": "^5.0.0",
+ "npm-package-arg": "^11.0.0",
+ "promzard": "^1.0.0",
+ "read": "^3.0.1",
+ "semver": "^7.3.5",
+ "validate-npm-package-license": "^3.0.4",
+ "validate-npm-package-name": "^5.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/ip-address": {
+ "version": "9.0.5",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "jsbn": "1.1.0",
+ "sprintf-js": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/npm/node_modules/ip-regex": {
+ "version": "5.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm/node_modules/is-cidr": {
+ "version": "5.0.5",
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "cidr-regex": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/npm/node_modules/is-core-module": {
+ "version": "2.13.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/npm/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/is-lambda": {
+ "version": "1.0.1",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/isexe": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/jackspeak": {
+ "version": "2.3.6",
+ "inBundle": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/npm/node_modules/jsbn": {
+ "version": "1.1.0",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/json-parse-even-better-errors": {
+ "version": "3.0.2",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/json-stringify-nice": {
+ "version": "1.1.4",
+ "inBundle": true,
+ "license": "ISC",
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/jsonparse": {
+ "version": "1.3.1",
+ "engines": [
+ "node >= 0.2.0"
+ ],
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/just-diff": {
+ "version": "6.0.2",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/just-diff-apply": {
+ "version": "5.5.0",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/libnpmaccess": {
+ "version": "8.0.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-package-arg": "^11.0.2",
+ "npm-registry-fetch": "^17.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmdiff": {
+ "version": "6.1.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/arborist": "^7.5.2",
+ "@npmcli/installed-package-contents": "^2.1.0",
+ "binary-extensions": "^2.3.0",
+ "diff": "^5.1.0",
+ "minimatch": "^9.0.4",
+ "npm-package-arg": "^11.0.2",
+ "pacote": "^18.0.6",
+ "tar": "^6.2.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmexec": {
+ "version": "8.1.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/arborist": "^7.5.2",
+ "@npmcli/run-script": "^8.1.0",
+ "ci-info": "^4.0.0",
+ "npm-package-arg": "^11.0.2",
+ "pacote": "^18.0.6",
+ "proc-log": "^4.2.0",
+ "read": "^3.0.1",
+ "read-package-json-fast": "^3.0.2",
+ "semver": "^7.3.7",
+ "walk-up-path": "^3.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmfund": {
+ "version": "5.0.10",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/arborist": "^7.5.2"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmhook": {
+ "version": "10.0.5",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "aproba": "^2.0.0",
+ "npm-registry-fetch": "^17.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmorg": {
+ "version": "6.0.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "aproba": "^2.0.0",
+ "npm-registry-fetch": "^17.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmpack": {
+ "version": "7.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/arborist": "^7.5.2",
+ "@npmcli/run-script": "^8.1.0",
+ "npm-package-arg": "^11.0.2",
+ "pacote": "^18.0.6"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmpublish": {
+ "version": "9.0.8",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "ci-info": "^4.0.0",
+ "normalize-package-data": "^6.0.1",
+ "npm-package-arg": "^11.0.2",
+ "npm-registry-fetch": "^17.0.1",
+ "proc-log": "^4.2.0",
+ "semver": "^7.3.7",
+ "sigstore": "^2.2.0",
+ "ssri": "^10.0.6"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmsearch": {
+ "version": "7.0.5",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-registry-fetch": "^17.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmteam": {
+ "version": "6.0.5",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "aproba": "^2.0.0",
+ "npm-registry-fetch": "^17.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmversion": {
+ "version": "6.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/git": "^5.0.7",
+ "@npmcli/run-script": "^8.1.0",
+ "json-parse-even-better-errors": "^3.0.2",
+ "proc-log": "^4.2.0",
+ "semver": "^7.3.7"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/lru-cache": {
+ "version": "10.2.2",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "14 || >=16.14"
+ }
+ },
+ "node_modules/npm/node_modules/make-fetch-happen": {
+ "version": "13.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/agent": "^2.0.0",
+ "cacache": "^18.0.0",
+ "http-cache-semantics": "^4.1.1",
+ "is-lambda": "^1.0.1",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^3.0.0",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "negotiator": "^0.6.3",
+ "proc-log": "^4.2.0",
+ "promise-retry": "^2.0.1",
+ "ssri": "^10.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/minimatch": {
+ "version": "9.0.4",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/minipass": {
+ "version": "7.1.1",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-collect": {
+ "version": "2.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-fetch": {
+ "version": "3.0.5",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "minipass": "^7.0.3",
+ "minipass-sized": "^1.0.3",
+ "minizlib": "^2.1.2"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ },
+ "optionalDependencies": {
+ "encoding": "^0.1.13"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-flush": {
+ "version": "1.0.5",
+ "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",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-json-stream": {
+ "version": "1.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "jsonparse": "^1.3.1",
+ "minipass": "^3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-json-stream/node_modules/minipass": {
+ "version": "3.3.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-pipeline": {
+ "version": "1.2.4",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": {
+ "version": "3.3.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-sized": {
+ "version": "1.0.3",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": {
+ "version": "3.3.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minizlib": {
+ "version": "2.1.2",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/npm/node_modules/minizlib/node_modules/minipass": {
+ "version": "3.3.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/mkdirp": {
+ "version": "1.0.4",
+ "inBundle": true,
+ "license": "MIT",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/ms": {
+ "version": "2.1.3",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/mute-stream": {
+ "version": "1.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/negotiator": {
+ "version": "0.6.3",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/npm/node_modules/node-gyp": {
+ "version": "10.1.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "env-paths": "^2.2.0",
+ "exponential-backoff": "^3.1.1",
+ "glob": "^10.3.10",
+ "graceful-fs": "^4.2.6",
+ "make-fetch-happen": "^13.0.0",
+ "nopt": "^7.0.0",
+ "proc-log": "^3.0.0",
+ "semver": "^7.3.5",
+ "tar": "^6.1.2",
+ "which": "^4.0.0"
+ },
+ "bin": {
+ "node-gyp": "bin/node-gyp.js"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/node-gyp/node_modules/proc-log": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/nopt": {
+ "version": "7.2.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "abbrev": "^2.0.0"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/normalize-package-data": {
+ "version": "6.0.1",
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "hosted-git-info": "^7.0.0",
+ "is-core-module": "^2.8.1",
+ "semver": "^7.3.5",
+ "validate-npm-package-license": "^3.0.4"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-audit-report": {
+ "version": "5.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-bundled": {
+ "version": "3.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-install-checks": {
+ "version": "6.3.0",
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "semver": "^7.1.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-normalize-package-bin": {
+ "version": "3.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-package-arg": {
+ "version": "11.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "hosted-git-info": "^7.0.0",
+ "proc-log": "^4.0.0",
+ "semver": "^7.3.5",
+ "validate-npm-package-name": "^5.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-packlist": {
+ "version": "8.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "ignore-walk": "^6.0.4"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-pick-manifest": {
+ "version": "9.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-install-checks": "^6.0.0",
+ "npm-normalize-package-bin": "^3.0.0",
+ "npm-package-arg": "^11.0.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-profile": {
+ "version": "10.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-registry-fetch": "^17.0.1",
+ "proc-log": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-registry-fetch": {
+ "version": "17.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/redact": "^2.0.0",
+ "make-fetch-happen": "^13.0.0",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^3.0.0",
+ "minipass-json-stream": "^1.0.1",
+ "minizlib": "^2.1.2",
+ "npm-package-arg": "^11.0.0",
+ "proc-log": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-user-validate": {
+ "version": "2.0.1",
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/p-map": {
+ "version": "4.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "aggregate-error": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm/node_modules/pacote": {
+ "version": "18.0.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/git": "^5.0.0",
+ "@npmcli/installed-package-contents": "^2.0.1",
+ "@npmcli/package-json": "^5.1.0",
+ "@npmcli/promise-spawn": "^7.0.0",
+ "@npmcli/run-script": "^8.0.0",
+ "cacache": "^18.0.0",
+ "fs-minipass": "^3.0.0",
+ "minipass": "^7.0.2",
+ "npm-package-arg": "^11.0.0",
+ "npm-packlist": "^8.0.0",
+ "npm-pick-manifest": "^9.0.0",
+ "npm-registry-fetch": "^17.0.0",
+ "proc-log": "^4.0.0",
+ "promise-retry": "^2.0.1",
+ "sigstore": "^2.2.0",
+ "ssri": "^10.0.0",
+ "tar": "^6.1.11"
+ },
+ "bin": {
+ "pacote": "bin/index.js"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/parse-conflict-json": {
+ "version": "3.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "json-parse-even-better-errors": "^3.0.0",
+ "just-diff": "^6.0.0",
+ "just-diff-apply": "^5.2.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/path-key": {
+ "version": "3.1.1",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/path-scurry": {
+ "version": "1.11.1",
+ "inBundle": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/postcss-selector-parser": {
+ "version": "6.0.16",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/npm/node_modules/proc-log": {
+ "version": "4.2.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/proggy": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/promise-all-reject-late": {
+ "version": "1.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/promise-call-limit": {
+ "version": "3.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/promise-inflight": {
+ "version": "1.0.1",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/promise-retry": {
+ "version": "2.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "err-code": "^2.0.2",
+ "retry": "^0.12.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/promzard": {
+ "version": "1.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "read": "^3.0.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/qrcode-terminal": {
+ "version": "0.12.0",
+ "inBundle": true,
+ "bin": {
+ "qrcode-terminal": "bin/qrcode-terminal.js"
+ }
+ },
+ "node_modules/npm/node_modules/read": {
+ "version": "3.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "mute-stream": "^1.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/read-cmd-shim": {
+ "version": "4.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/read-package-json-fast": {
+ "version": "3.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "json-parse-even-better-errors": "^3.0.0",
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/retry": {
+ "version": "0.12.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/npm/node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/semver": {
+ "version": "7.6.2",
+ "inBundle": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/shebang-command": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/signal-exit": {
+ "version": "4.1.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/sigstore": {
+ "version": "2.3.0",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@sigstore/bundle": "^2.3.1",
+ "@sigstore/core": "^1.0.0",
+ "@sigstore/protobuf-specs": "^0.3.1",
+ "@sigstore/sign": "^2.3.0",
+ "@sigstore/tuf": "^2.3.1",
+ "@sigstore/verify": "^1.2.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/smart-buffer": {
+ "version": "4.2.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/socks": {
+ "version": "2.8.3",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ip-address": "^9.0.5",
+ "smart-buffer": "^4.2.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/socks-proxy-agent": {
+ "version": "8.0.3",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.1",
+ "debug": "^4.3.4",
+ "socks": "^2.7.1"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/npm/node_modules/spdx-correct": {
+ "version": "3.2.0",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/spdx-exceptions": {
+ "version": "2.5.0",
+ "inBundle": true,
+ "license": "CC-BY-3.0"
+ },
+ "node_modules/npm/node_modules/spdx-expression-parse": {
+ "version": "4.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/spdx-license-ids": {
+ "version": "3.0.17",
+ "inBundle": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/npm/node_modules/sprintf-js": {
+ "version": "1.1.3",
+ "inBundle": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/npm/node_modules/ssri": {
+ "version": "10.0.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/string-width": {
+ "version": "4.2.3",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/supports-color": {
+ "version": "9.4.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/tar": {
+ "version": "6.2.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^5.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/tar/node_modules/fs-minipass": {
+ "version": "2.1.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
},
- "node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
+ "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": {
+ "version": "3.3.6",
+ "inBundle": true,
+ "license": "ISC",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=8"
}
},
- "node_modules/map-obj": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
- "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
- "dev": true,
+ "node_modules/npm/node_modules/tar/node_modules/minipass": {
+ "version": "5.0.0",
+ "inBundle": true,
+ "license": "ISC",
"engines": {
"node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/mathml-tag-names": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz",
- "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==",
- "dev": true,
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
+ "node_modules/npm/node_modules/text-table": {
+ "version": "0.2.0",
+ "inBundle": true,
+ "license": "MIT"
},
- "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==",
- "dev": true
+ "node_modules/npm/node_modules/tiny-relative-date": {
+ "version": "1.3.0",
+ "inBundle": true,
+ "license": "MIT"
},
- "node_modules/meow": {
- "version": "10.1.5",
- "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz",
- "integrity": "sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==",
- "dev": true,
+ "node_modules/npm/node_modules/treeverse": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/tuf-js": {
+ "version": "2.2.1",
+ "inBundle": true,
+ "license": "MIT",
"dependencies": {
- "@types/minimist": "^1.2.2",
- "camelcase-keys": "^7.0.0",
- "decamelize": "^5.0.0",
- "decamelize-keys": "^1.1.0",
- "hard-rejection": "^2.1.0",
- "minimist-options": "4.1.0",
- "normalize-package-data": "^3.0.2",
- "read-pkg-up": "^8.0.0",
- "redent": "^4.0.0",
- "trim-newlines": "^4.0.2",
- "type-fest": "^1.2.2",
- "yargs-parser": "^20.2.9"
+ "@tufjs/models": "2.0.1",
+ "debug": "^4.3.4",
+ "make-fetch-happen": "^13.0.1"
},
"engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": "^16.14.0 || >=18.0.0"
}
},
- "node_modules/meow/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==",
- "dev": true,
+ "node_modules/npm/node_modules/unique-filename": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "unique-slug": "^4.0.0"
+ },
"engines": {
- "node": ">=10"
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/unique-slug": {
+ "version": "4.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4"
},
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "dev": true,
+ "node_modules/npm/node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/validate-npm-package-license": {
+ "version": "3.0.4",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/validate-npm-package-name": {
+ "version": "5.0.1",
+ "inBundle": true,
+ "license": "ISC",
"engines": {
- "node": ">= 8"
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
- "node_modules/micromatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
- "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
- "dev": true,
+ "node_modules/npm/node_modules/walk-up-path": {
+ "version": "3.0.1",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/which": {
+ "version": "4.0.0",
+ "inBundle": true,
+ "license": "ISC",
"dependencies": {
- "braces": "^3.0.2",
- "picomatch": "^2.3.1"
+ "isexe": "^3.1.1"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
},
"engines": {
- "node": ">=8.6"
+ "node": "^16.13.0 || >=18.0.0"
}
},
- "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==",
- "dev": true,
+ "node_modules/npm/node_modules/which/node_modules/isexe": {
+ "version": "3.1.1",
+ "inBundle": true,
+ "license": "ISC",
"engines": {
- "node": ">=4"
+ "node": ">=16"
}
},
- "node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
+ "node_modules/npm/node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "inBundle": true,
+ "license": "MIT",
"dependencies": {
- "brace-expansion": "^1.1.7"
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
},
"engines": {
- "node": "*"
- }
- },
- "node_modules/minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
- "dev": true,
+ "node": ">=12"
+ },
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
- "node_modules/minimist-options": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
- "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
- "dev": true,
+ "node_modules/npm/node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "inBundle": true,
+ "license": "MIT",
"dependencies": {
- "arrify": "^1.0.1",
- "is-plain-obj": "^1.1.0",
- "kind-of": "^6.0.3"
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
},
"engines": {
- "node": ">= 6"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
- "node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true
- },
- "node_modules/nanoid": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
- "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "bin": {
- "nanoid": "bin/nanoid.cjs"
+ "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
},
"engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/natural-compare": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
- "dev": true
+ "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
},
- "node_modules/node-releases": {
- "version": "2.0.13",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
- "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
- "dev": true,
- "peer": true
+ "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "inBundle": true,
+ "license": "MIT"
},
- "node_modules/normalize-package-data": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
- "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
- "dev": true,
+ "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": {
+ "version": "5.1.2",
+ "inBundle": true,
+ "license": "MIT",
"dependencies": {
- "hosted-git-info": "^4.0.1",
- "is-core-module": "^2.5.0",
- "semver": "^7.3.4",
- "validate-npm-package-license": "^3.0.1"
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
},
"engines": {
- "node": ">=10"
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/normalize-package-data/node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "dev": true,
+ "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "inBundle": true,
+ "license": "MIT",
"dependencies": {
- "lru-cache": "^6.0.0"
+ "ansi-regex": "^6.0.1"
},
- "bin": {
- "semver": "bin/semver.js"
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/write-file-atomic": {
+ "version": "5.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^4.0.1"
},
"engines": {
- "node": ">=10"
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "node_modules/npm/node_modules/yallist": {
+ "version": "4.0.0",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/object-inspect": {
- "version": "1.12.3",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
- "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
+ "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -3070,13 +7846,13 @@
}
},
"node_modules/object.assign": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
- "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
+ "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
+ "call-bind": "^1.0.5",
+ "define-properties": "^1.2.1",
"has-symbols": "^1.0.3",
"object-keys": "^1.1.1"
},
@@ -3152,8 +7928,32 @@
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
- "dependencies": {
- "wrappy": "1"
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
+ "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
+ "dev": true,
+ "dependencies": {
+ "mimic-fn": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/opener": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
+ "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
+ "dev": true,
+ "bin": {
+ "opener": "bin/opener-bin.js"
}
},
"node_modules/optionator": {
@@ -3173,6 +7973,42 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/p-each-series": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz",
+ "integrity": "sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-filter": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-4.1.0.tgz",
+ "integrity": "sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==",
+ "dev": true,
+ "dependencies": {
+ "p-map": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -3203,6 +8039,39 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/p-map": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.2.tgz",
+ "integrity": "sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-reduce": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz",
+ "integrity": "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -3233,6 +8102,39 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/parse-ms": {
+ "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,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
+ "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+ "dev": true,
+ "dependencies": {
+ "parse5": "^6.0.1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
+ "dev": true
+ },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -3293,10 +8195,152 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pkg-conf": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz",
+ "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^2.0.0",
+ "load-json-file": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pkg-conf/node_modules/find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pkg-conf/node_modules/locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pkg-conf/node_modules/p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pkg-conf/node_modules/p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pkg-conf/node_modules/path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/playwright": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.0.tgz",
+ "integrity": "sha512-F9b3GUCLQ3Nffrfb6dunPOkE5Mh68tR7zN32L4jCk4FjQamgesGay7/dAAe1WaMEGV04DkdJfcJzjoCKygUaRQ==",
+ "dev": true,
+ "dependencies": {
+ "playwright-core": "1.44.0"
+ },
+ "bin": {
+ "playwright": "cli.js"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "optionalDependencies": {
+ "fsevents": "2.3.2"
+ }
+ },
+ "node_modules/playwright-core": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.0.tgz",
+ "integrity": "sha512-ZTbkNpFfYcGWohvTTl+xewITm7EOuqIqex0c7dNZ+aXsbrLj0qI8XlGKfPpipjm0Wny/4Lt4CJsWJk1stVS5qQ==",
+ "dev": true,
+ "bin": {
+ "playwright-core": "cli.js"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/portfinder": {
+ "version": "1.0.32",
+ "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
+ "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==",
+ "dev": true,
+ "dependencies": {
+ "async": "^2.6.4",
+ "debug": "^3.2.7",
+ "mkdirp": "^0.5.6"
+ },
+ "engines": {
+ "node": ">= 0.12.0"
+ }
+ },
+ "node_modules/portfinder/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/possible-typed-array-names": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
+ "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/postcss": {
- "version": "8.4.29",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz",
- "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==",
+ "version": "8.4.38",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
+ "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
"dev": true,
"funding": [
{
@@ -3313,9 +8357,9 @@
}
],
"dependencies": {
- "nanoid": "^3.3.6",
+ "nanoid": "^3.3.7",
"picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
+ "source-map-js": "^1.2.0"
},
"engines": {
"node": "^10 || ^12 || >=14"
@@ -3371,6 +8415,33 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/pretty-ms": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.0.0.tgz",
+ "integrity": "sha512-E9e9HJ9R9NasGOgPaPE8VMeiPKAyWR5jcFpNnwIejslIhWqdqOrb2wShBsncMPUb+BcCd2OPYfh7p2W6oemTng==",
+ "dev": true,
+ "dependencies": {
+ "parse-ms": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true
+ },
+ "node_modules/proto-list": {
+ "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
+ },
"node_modules/punycode": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
@@ -3380,6 +8451,21 @@
"node": ">=6"
}
},
+ "node_modules/qs": {
+ "version": "6.12.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz",
+ "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==",
+ "dev": true,
+ "dependencies": {
+ "side-channel": "^1.0.6"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -3412,6 +8498,143 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "dev": true,
+ "dependencies": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "bin": {
+ "rc": "cli.js"
+ }
+ },
+ "node_modules/rc/node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/read-package-up": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz",
+ "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==",
+ "dev": true,
+ "dependencies": {
+ "find-up-simple": "^1.0.0",
+ "read-pkg": "^9.0.0",
+ "type-fest": "^4.6.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/read-package-up/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,
+ "dependencies": {
+ "lru-cache": "^10.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/read-package-up/node_modules/lru-cache": {
+ "version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz",
+ "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==",
+ "dev": true,
+ "engines": {
+ "node": "14 || >=16.14"
+ }
+ },
+ "node_modules/read-package-up/node_modules/normalize-package-data": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.1.tgz",
+ "integrity": "sha512-6rvCfeRW+OEZagAB4lMLSNuTNYZWLVtKccK79VSTf//yTY5VOCgcpH80O+bZK8Neps7pUnd5G+QlMg1yV/2iZQ==",
+ "dev": true,
+ "dependencies": {
+ "hosted-git-info": "^7.0.0",
+ "is-core-module": "^2.8.1",
+ "semver": "^7.3.5",
+ "validate-npm-package-license": "^3.0.4"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/read-package-up/node_modules/parse-json": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz",
+ "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.22.13",
+ "index-to-position": "^0.1.2",
+ "type-fest": "^4.7.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/read-package-up/node_modules/read-pkg": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz",
+ "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==",
+ "dev": true,
+ "dependencies": {
+ "@types/normalize-package-data": "^2.4.3",
+ "normalize-package-data": "^6.0.0",
+ "parse-json": "^8.0.0",
+ "type-fest": "^4.6.0",
+ "unicorn-magic": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/read-package-up/node_modules/semver": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/read-package-up/node_modules/type-fest": {
+ "version": "4.18.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.18.2.tgz",
+ "integrity": "sha512-+suCYpfJLAe4OXS6+PPXjW3urOS4IoP9waSiLuXfLgqZODKw/aWwASvzqE886wA0kQgGy0mIWyhd87VpqIy6Xg==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/read-pkg": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-6.0.0.tgz",
@@ -3471,6 +8694,27 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dev": true,
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/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
+ },
"node_modules/redent": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz",
@@ -3488,14 +8732,15 @@
}
},
"node_modules/regexp.prototype.flags": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz",
- "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
+ "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "functions-have-names": "^1.2.3"
+ "call-bind": "^1.0.6",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "set-function-name": "^2.0.1"
},
"engines": {
"node": ">= 0.4"
@@ -3504,6 +8749,27 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/registry-auth-token": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz",
+ "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==",
+ "dev": true,
+ "dependencies": {
+ "@pnpm/npm-conf": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
@@ -3513,6 +8779,12 @@
"node": ">=0.10.0"
}
},
+ "node_modules/requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "dev": true
+ },
"node_modules/resolve": {
"version": "1.22.4",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz",
@@ -3588,13 +8860,13 @@
}
},
"node_modules/safe-array-concat": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz",
- "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz",
+ "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.2.0",
+ "call-bind": "^1.0.7",
+ "get-intrinsic": "^1.2.4",
"has-symbols": "^1.0.3",
"isarray": "^2.0.5"
},
@@ -3605,20 +8877,152 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
"node_modules/safe-regex-test": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
- "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz",
+ "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.3",
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
"is-regex": "^1.1.4"
},
+ "engines": {
+ "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==",
+ "dev": true
+ },
+ "node_modules/secure-compare": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz",
+ "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==",
+ "dev": true
+ },
+ "node_modules/semantic-release": {
+ "version": "23.1.1",
+ "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-23.1.1.tgz",
+ "integrity": "sha512-qqJDBhbtHsjUEMsojWKGuL5lQFCJuPtiXKEIlFKyTzDDGTAE/oyvznaP8GeOr5PvcqBJ6LQz4JCENWPLeehSpA==",
+ "dev": true,
+ "dependencies": {
+ "@semantic-release/commit-analyzer": "^12.0.0",
+ "@semantic-release/error": "^4.0.0",
+ "@semantic-release/github": "^10.0.0",
+ "@semantic-release/npm": "^12.0.0",
+ "@semantic-release/release-notes-generator": "^13.0.0",
+ "aggregate-error": "^5.0.0",
+ "cosmiconfig": "^9.0.0",
+ "debug": "^4.0.0",
+ "env-ci": "^11.0.0",
+ "execa": "^9.0.0",
+ "figures": "^6.0.0",
+ "find-versions": "^6.0.0",
+ "get-stream": "^6.0.0",
+ "git-log-parser": "^1.2.0",
+ "hook-std": "^3.0.0",
+ "hosted-git-info": "^7.0.0",
+ "import-from-esm": "^1.3.1",
+ "lodash-es": "^4.17.21",
+ "marked": "^12.0.0",
+ "marked-terminal": "^7.0.0",
+ "micromatch": "^4.0.2",
+ "p-each-series": "^3.0.0",
+ "p-reduce": "^3.0.0",
+ "read-package-up": "^11.0.0",
+ "resolve-from": "^5.0.0",
+ "semver": "^7.3.2",
+ "semver-diff": "^4.0.0",
+ "signale": "^1.2.1",
+ "yargs": "^17.5.1"
+ },
+ "bin": {
+ "semantic-release": "bin/semantic-release.js"
+ },
+ "engines": {
+ "node": ">=20.8.1"
+ }
+ },
+ "node_modules/semantic-release/node_modules/cosmiconfig": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
+ "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
+ "dev": true,
+ "dependencies": {
+ "env-paths": "^2.2.1",
+ "import-fresh": "^3.3.0",
+ "js-yaml": "^4.1.0",
+ "parse-json": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/d-fischer"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.9.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/semantic-release/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,
+ "dependencies": {
+ "lru-cache": "^10.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/semantic-release/node_modules/lru-cache": {
+ "version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz",
+ "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==",
+ "dev": true,
+ "engines": {
+ "node": "14 || >=16.14"
+ }
+ },
+ "node_modules/semantic-release/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/semantic-release/node_modules/semver": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
@@ -3628,6 +9032,77 @@
"semver": "bin/semver.js"
}
},
+ "node_modules/semver-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz",
+ "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/semver-diff/node_modules/semver": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dev": true,
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/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==",
+ "dev": true,
+ "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/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -3650,14 +9125,18 @@
}
},
"node_modules/side-channel": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
- "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
+ "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.0",
- "get-intrinsic": "^1.0.2",
- "object-inspect": "^1.9.0"
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.4",
+ "object-inspect": "^1.13.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -3675,6 +9154,115 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/signale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz",
+ "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^2.3.2",
+ "figures": "^2.0.0",
+ "pkg-conf": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/signale/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/signale/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/signale/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/signale/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/signale/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/signale/node_modules/figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "^1.0.5"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/signale/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/signale/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/skin-tone": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz",
+ "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==",
+ "dev": true,
+ "dependencies": {
+ "unicode-emoji-modifier-base": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -3701,15 +9289,30 @@
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
}
},
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/source-map-js": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
- "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
+ "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
+ "node_modules/spawn-error-forwarder": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz",
+ "integrity": "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==",
+ "dev": true
+ },
"node_modules/spdx-correct": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
@@ -3742,6 +9345,34 @@
"integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==",
"dev": true
},
+ "node_modules/split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10.x"
+ }
+ },
+ "node_modules/stream-combiner2": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz",
+ "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==",
+ "dev": true,
+ "dependencies": {
+ "duplexer2": "~0.1.0",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
"node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
@@ -3757,14 +9388,15 @@
}
},
"node_modules/string.prototype.trim": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz",
- "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==",
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz",
+ "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.0",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -3774,28 +9406,31 @@
}
},
"node_modules/string.prototype.trimend": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz",
- "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz",
+ "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/string.prototype.trimstart": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz",
- "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
+ "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"
@@ -3822,6 +9457,18 @@
"node": ">=4"
}
},
+ "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,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/strip-indent": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz",
@@ -3955,6 +9602,22 @@
"node": ">=8"
}
},
+ "node_modules/super-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-1.0.0.tgz",
+ "integrity": "sha512-CY8u7DtbvucKuquCmOFEKhr9Besln7n9uN8eFbwcoGYWXOMW07u2o8njWaiXt11ylS3qoGF55pILjRmPlbodyg==",
+ "dev": true,
+ "dependencies": {
+ "function-timeout": "^1.0.1",
+ "time-span": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -4036,12 +9699,127 @@
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true
},
+ "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==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ }
+ },
+ "node_modules/tempy": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz",
+ "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==",
+ "dev": true,
+ "dependencies": {
+ "is-stream": "^3.0.0",
+ "temp-dir": "^3.0.0",
+ "type-fest": "^2.12.2",
+ "unique-string": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/tempy/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,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/tempy/node_modules/type-fest": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
+ "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/text-extensions": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz",
+ "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true
},
+ "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,
+ "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,
+ "dependencies": {
+ "thenify": ">= 3.1.0 < 4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "dev": true
+ },
+ "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,
+ "dependencies": {
+ "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,
+ "dependencies": {
+ "convert-hrtime": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
@@ -4064,6 +9842,23 @@
"node": ">=8.0"
}
},
+ "node_modules/traverse": {
+ "version": "0.6.9",
+ "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.9.tgz",
+ "integrity": "sha512-7bBrcF+/LQzSgFmT0X5YclVqQxtv7TDJ1f8Wj7ibBu/U6BMLeOpUxuZjV7rMc44UtKxlnMFigdhFAIszSX1DMg==",
+ "dev": true,
+ "dependencies": {
+ "gopd": "^1.0.1",
+ "typedarray.prototype.slice": "^1.0.3",
+ "which-typed-array": "^1.1.15"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/trim-newlines": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.1.1.tgz",
@@ -4088,6 +9883,12 @@
"strip-bom": "^3.0.0"
}
},
+ "node_modules/turbogrid": {
+ "version": "3.0.13",
+ "resolved": "https://registry.npmjs.org/turbogrid/-/turbogrid-3.0.13.tgz",
+ "integrity": "sha512-8owt3hf29VDyW9excRMGccq/cmqspmvg8Zt6JgXw2uuq65drl50KXtGQpGevIbqQMnvltyfyLLJjzNnWK7tCVA==",
+ "dev": true
+ },
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -4113,29 +9914,30 @@
}
},
"node_modules/typed-array-buffer": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz",
- "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
+ "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.2.1",
- "is-typed-array": "^1.1.10"
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.13"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/typed-array-byte-length": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz",
- "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz",
+ "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
+ "call-bind": "^1.0.7",
"for-each": "^0.3.3",
- "has-proto": "^1.0.1",
- "is-typed-array": "^1.1.10"
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13"
},
"engines": {
"node": ">= 0.4"
@@ -4145,16 +9947,17 @@
}
},
"node_modules/typed-array-byte-offset": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz",
- "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz",
+ "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==",
"dev": true,
"dependencies": {
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.2",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
"for-each": "^0.3.3",
- "has-proto": "^1.0.1",
- "is-typed-array": "^1.1.10"
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13"
},
"engines": {
"node": ">= 0.4"
@@ -4164,19 +9967,58 @@
}
},
"node_modules/typed-array-length": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
- "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz",
+ "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
+ "call-bind": "^1.0.7",
"for-each": "^0.3.3",
- "is-typed-array": "^1.1.9"
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13",
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typedarray.prototype.slice": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typedarray.prototype.slice/-/typedarray.prototype.slice-1.0.3.tgz",
+ "integrity": "sha512-8WbVAQAUlENo1q3c3zZYuy5k9VzBQvp8AX9WOtbvyWlLM1v5JaSRmjubLjzHF4JFtptjH/5c/i95yaElvcjC0A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.0",
+ "es-errors": "^1.3.0",
+ "typed-array-buffer": "^1.0.2",
+ "typed-array-byte-offset": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/uglify-js": {
+ "version": "3.17.4",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz",
+ "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
+ "dev": true,
+ "optional": true,
+ "bin": {
+ "uglifyjs": "bin/uglifyjs"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
"node_modules/unbox-primitive": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
@@ -4192,6 +10034,69 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "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,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicorn-magic": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
+ "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/union": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz",
+ "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==",
+ "dev": true,
+ "dependencies": {
+ "qs": "^6.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "crypto-random-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/universal-user-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
+ "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==",
+ "dev": true
+ },
+ "node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
"node_modules/update-browserslist-db": {
"version": "1.0.13",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
@@ -4232,6 +10137,15 @@
"punycode": "^2.1.0"
}
},
+ "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,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -4248,6 +10162,18 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "node_modules/whatwg-encoding": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
+ "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
+ "dev": true,
+ "dependencies": {
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -4280,16 +10206,16 @@
}
},
"node_modules/which-typed-array": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz",
- "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==",
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
+ "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
"dev": true,
"dependencies": {
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.2",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
- "has-tostringtag": "^1.0.0"
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -4298,6 +10224,29 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
+ "dev": true
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@@ -4317,12 +10266,48 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
+ "node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "dev": true,
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/yargs-parser": {
"version": "20.2.9",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
@@ -4332,6 +10317,15 @@
"node": ">=10"
}
},
+ "node_modules/yargs/node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
@@ -4343,6 +10337,18 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
+ },
+ "node_modules/yoctocolors": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.0.2.tgz",
+ "integrity": "sha512-Ct97huExsu7cWeEjmrXlofevF8CvzUglJ4iGUet5B8xn1oumtAZBpHU4GzYuoE6PVqcZ5hghtBrSlhwHuR1Jmw==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
}
}
}
diff --git a/plugins/experimentation/package.json b/plugins/experimentation/package.json
index 97fb757c..2c2741cc 100644
--- a/plugins/experimentation/package.json
+++ b/plugins/experimentation/package.json
@@ -1,11 +1,13 @@
{
"name": "@adobe/aem-experimentation",
- "version": "1.0.0",
+ "version": "1.0.1",
"main": "src/index.js",
"scripts": {
"lint:js": "eslint src",
"lint:css": "stylelint src/**/*.css",
- "lint": "npm run lint:js && npm run lint:css"
+ "lint": "npm run lint:js && npm run lint:css",
+ "start": "http-server . -p 3000",
+ "test": "playwright test"
},
"repository": {
"type": "git",
@@ -28,10 +30,18 @@
"homepage": "https://github.com/adobe/aem-experimentation#readme",
"devDependencies": {
"@babel/eslint-parser": "7.22.15",
+ "@playwright/test": "1.44.0",
+ "@semantic-release/changelog": "6.0.3",
+ "@semantic-release/git": "10.0.1",
+ "@semantic-release/npm": "12.0.1",
"eslint": "8.48.0",
"eslint-config-airbnb-base": "15.0.0",
"eslint-plugin-import": "2.28.1",
+ "http-server": "14.1.1",
+ "monocart-coverage-reports": "2.8.2",
+ "semantic-release": "23.1.1",
"stylelint": "15.10.3",
"stylelint-config-standard": "34.0.0"
- }
+ },
+ "private": true
}
diff --git a/plugins/experimentation/playwright.config.js b/plugins/experimentation/playwright.config.js
new file mode 100644
index 00000000..b3a6d4a2
--- /dev/null
+++ b/plugins/experimentation/playwright.config.js
@@ -0,0 +1,54 @@
+/* eslint-disable import/no-extraneous-dependencies */
+import { defineConfig, devices } from '@playwright/test';
+
+/**
+ * Read environment variables from file.
+ * https://github.com/motdotla/dotenv
+ */
+// require('dotenv').config();
+
+/**
+ * @see https://playwright.dev/docs/test-configuration
+ */
+export default defineConfig({
+ testDir: './tests',
+ /* Run tests in files in parallel */
+ fullyParallel: true,
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: process.env.CI ? 'line' : 'html',
+ use: {
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: 'http://127.0.0.1:3000/',
+
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+ },
+
+ globalSetup: './tests/setup.js',
+ globalTeardown: './tests/teardown.js',
+
+ /* Configure the tests for the top 3 browsers that access the site */
+ projects: [
+ {
+ name: 'Desktop Chrome',
+ use: { ...devices['Desktop Chrome'] },
+ },
+ ],
+
+ timeout: 10000,
+
+ // Run your local dev server before starting the tests
+ webServer: {
+ command: 'npm run start',
+ url: 'http://127.0.0.1:3000',
+ reuseExistingServer: !process.env.CI,
+ stdout: 'ignore',
+ stderr: 'pipe',
+ },
+});
diff --git a/plugins/experimentation/src/index.js b/plugins/experimentation/src/index.js
index 5ee2136a..fc456ebe 100644
--- a/plugins/experimentation/src/index.js
+++ b/plugins/experimentation/src/index.js
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 Adobe. All rights reserved.
+ * Copyright 2024 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
@@ -9,11 +9,27 @@
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
-const MAX_SAMPLING_RATE = 10; // At a maximum we sample 1 in 10 requests
+
+let isDebugEnabled;
+export function setDebugMode(url, pluginOptions) {
+ const { host, hostname, origin } = url;
+ const { isProd, prodHost } = pluginOptions;
+ isDebugEnabled = (url.hostname === 'localhost'
+ || url.hostname.endsWith('.page')
+ || (typeof isProd === 'function' && !isProd())
+ || (prodHost && ![host, hostname, origin].includes(prodHost))
+ || false);
+ return isDebugEnabled;
+}
+
+export function debug(...args) {
+ if (isDebugEnabled) {
+ // eslint-disable-next-line no-console
+ console.debug.call(this, '[aem-experimentation]', ...args);
+ }
+}
export const DEFAULT_OPTIONS = {
- // Generic properties
- rumSamplingRate: MAX_SAMPLING_RATE, // 1 in 10 requests
// Audiences related properties
audiences: {},
@@ -25,60 +41,157 @@ export const DEFAULT_OPTIONS = {
campaignsQueryParameter: 'campaign',
// Experimentation related properties
- experimentsRoot: '/experiments',
- experimentsConfigFile: 'manifest.json',
- experimentsMetaTag: 'experiment',
+ experimentsMetaTagPrefix: 'experiment',
experimentsQueryParameter: 'experiment',
};
/**
- * Checks if the current engine is detected as being a bot.
- * @returns `true` if the current engine is detected as being, `false` otherwise
+ * Converts a given comma-seperate string to an array.
+ * @param {String|String[]} str The string to convert
+ * @returns an array representing the converted string
*/
-function isBot() {
- return navigator.userAgent.match(/bot|crawl|spider/i);
+export function stringToArray(str) {
+ if (Array.isArray(str)) {
+ return str;
+ }
+ return str ? str.split(/[,\n]/).filter((s) => s.trim()) : [];
}
/**
- * Checks if any of the configured audiences on the page can be resolved.
- * @param {string[]} applicableAudiences a list of configured audiences for the page
- * @param {object} options the plugin options
- * @returns Returns the names of the resolved audiences, or `null` if no audience is configured
+ * Sanitizes a name for use as class name.
+ * @param {String} name The unsanitized name
+ * @returns {String} The class name
*/
-export async function getResolvedAudiences(applicableAudiences, options, context) {
- if (!applicableAudiences.length || !Object.keys(options.audiences).length) {
- return null;
- }
- // If we have a forced audience set in the query parameters (typically for simulation purposes)
- // we check if it is applicable
+export function toClassName(name) {
+ return typeof name === 'string'
+ ? name.toLowerCase().replace(/[^0-9a-z]/gi, '-').replace(/-+/g, '-').replace(/^-|-$/g, '')
+ : '';
+}
+
+/**
+ * Sanitizes a name for use as a js property name.
+ * @param {String} name The unsanitized name
+ * @returns {String} The camelCased name
+ */
+export function toCamelCase(name) {
+ return toClassName(name).replace(/-([a-z])/g, (g) => g[1].toUpperCase());
+}
+
+/**
+ * Retrieves the content of metadata tags.
+ * @param {String} name The metadata name (or property)
+ * @returns {String} The metadata value(s)
+ */
+export function getMetadata(name) {
+ const meta = [...document.head.querySelectorAll(`meta[name="${name}"]`)].map((m) => m.content).join(', ');
+ return meta || '';
+}
+
+/**
+ * Gets all the metadata elements that are in the given scope.
+ * @param {String} scope The scope/prefix for the metadata
+ * @returns a map of key/value pairs for the given scope
+ */
+export function getAllMetadata(scope) {
+ const value = getMetadata(scope);
+ const metaTags = document.head.querySelectorAll(`meta[name^="${scope}-"], meta[property^="${scope}:-"]`);
+
+ return [...metaTags].reduce((res, meta) => {
+ const key = meta.getAttribute('name')
+ ? meta.getAttribute('name').substring(scope.length + 1)
+ : meta.getAttribute('property').substring(scope.length + 2);
+
+ const camelCaseKey = toCamelCase(key);
+ res[camelCaseKey] = meta.getAttribute('content');
+
+ return res;
+ }, value ? { value } : {});
+}
+
+/**
+ * Gets all the data attributes that are in the given scope.
+ * @param {String} scope The scope/prefix for the metadata
+ * @returns a map of key/value pairs for the given scope
+ */
+// eslint-disable-next-line no-unused-vars
+function getAllDataAttributes(el, scope) {
+ return el.getAttributeNames()
+ .filter((attr) => attr === `data-${scope}` || attr.startsWith(`data-${scope}-`))
+ .reduce((res, attr) => {
+ const key = attr === `data-${scope}` ? 'value' : attr.replace(`data-${scope}-`, '');
+ res[key] = el.getAttribute(attr);
+ return res;
+ }, {});
+}
+
+/**
+ * Gets all the query parameters that are in the given scope.
+ * @param {String} scope The scope/prefix for the metadata
+ * @returns a map of key/value pairs for the given scope
+ */
+function getAllQueryParameters(scope) {
const usp = new URLSearchParams(window.location.search);
- const forcedAudience = usp.has(options.audiencesQueryParameter)
- ? context.toClassName(usp.get(options.audiencesQueryParameter))
- : null;
- if (forcedAudience) {
- return applicableAudiences.includes(forcedAudience) ? [forcedAudience] : [];
- }
+ return [...usp.entries()]
+ .filter(([param]) => param === scope || param.startsWith(`${scope}-`))
+ .reduce((res, [param, value]) => {
+ const key = param === scope ? 'value' : param.replace(`${scope}-`, '');
+ if (res[key]) {
+ res[key] = [].concat(res[key], value);
+ } else {
+ res[key] = value;
+ }
+ return res;
+ }, {});
+}
- // Otherwise, return the list of audiences that are resolved on the page
- const results = await Promise.all(
- applicableAudiences
- .map((key) => {
- if (options.audiences[key] && typeof options.audiences[key] === 'function') {
- return options.audiences[key]();
+/**
+ * Extracts the config from a block that is in the given scope.
+ * @param {HTMLElement} block The block element
+ * @returns a map of key/value pairs for the given scope
+ */
+// eslint-disable-next-line import/prefer-default-export
+function getAllSectionMeta(block, scope) {
+ const config = {};
+ block.querySelectorAll(':scope > div').forEach((row) => {
+ if (row.children) {
+ const cols = [...row.children];
+ if (cols[1]) {
+ const col = cols[1];
+ let key = toClassName(cols[0].textContent);
+ if (key !== scope && !key.startsWith(`${scope}-`)) {
+ return;
}
- return false;
- }),
- );
- return applicableAudiences.filter((_, i) => results[i]);
+ key = key === scope ? 'value' : key.replace(`${scope}-`, '');
+ let value = '';
+ if (col.querySelector('a')) {
+ const as = [...col.querySelectorAll('a')];
+ if (as.length === 1) {
+ value = as[0].href;
+ } else {
+ value = as.map((a) => a.href);
+ }
+ } else if (col.querySelector('p')) {
+ const ps = [...col.querySelectorAll('p')];
+ if (ps.length === 1) {
+ value = ps[0].textContent;
+ } else {
+ value = ps.map((p) => p.textContent);
+ }
+ } else value = row.children[1].textContent;
+ config[key] = value;
+ }
+ }
+ });
+ return config;
}
/**
* Replaces element with content from path
- * @param {string} path
- * @param {HTMLElement} main
+ * @param {String} path
+ * @param {HTMLElement} el
* @return Returns the path that was loaded or null if the loading failed
*/
-async function replaceInner(path, main) {
+async function replaceInner(path, el, selector) {
try {
const resp = await fetch(path);
if (!resp.ok) {
@@ -89,9 +202,15 @@ async function replaceInner(path, main) {
const html = await resp.text();
// parse with DOMParser to guarantee valid HTML, and no script execution(s)
const dom = new DOMParser().parseFromString(html, 'text/html');
- // do not use replaceWith API here since this would replace the main reference
- // in scripts.js as well and prevent proper decoration of the sections/blocks
- main.innerHTML = dom.querySelector('main').innerHTML;
+ // eslint-disable-next-line no-param-reassign
+ let newEl;
+ if (selector) {
+ newEl = dom.querySelector(selector);
+ }
+ if (!newEl) {
+ newEl = dom.querySelector(el.tagName === 'MAIN' ? 'main' : 'main > div');
+ }
+ el.innerHTML = newEl.innerHTML;
return path;
} catch (e) {
// eslint-disable-next-line no-console
@@ -101,93 +220,36 @@ async function replaceInner(path, main) {
}
/**
- * Parses the experimentation configuration sheet and creates an internal model.
- *
- * Output model is expected to have the following structure:
- * {
- * id: ,
- * label: ,
- * blocks: ,
- * audiences: [],
- * status: Active | Inactive,
- * variantNames: [],
- * variants: {
- * [variantName]: {
- * label:
- * percentageSplit: ,
- * pages: ,
- * blocks: ,
- * }
- * }
- * };
+ * Checks if any of the configured audiences on the page can be resolved.
+ * @param {String[]} pageAudiences a list of configured audiences for the page
+ * @param {Object} options the plugin options
+ * @returns Returns the names of the resolved audiences, or `null` if no audience is configured
*/
-function parseExperimentConfig(json, context) {
- const config = {};
- try {
- json.settings.data.forEach((line) => {
- const key = context.toCamelCase(line.Name);
- if (key === 'audience' || key === 'audiences') {
- config.audiences = line.Value ? line.Value.split(',').map((str) => str.trim()) : [];
- } else if (key === 'experimentName') {
- config.label = line.Value;
- } else {
- config[key] = line.Value;
- }
- });
- const variants = {};
- let variantNames = Object.keys(json.experiences.data[0]);
- variantNames.shift();
- variantNames = variantNames.map((vn) => context.toCamelCase(vn));
- variantNames.forEach((variantName) => {
- variants[variantName] = {};
- });
- let lastKey = 'default';
- json.experiences.data.forEach((line) => {
- let key = context.toCamelCase(line.Name);
- if (!key) key = lastKey;
- lastKey = key;
- const vns = Object.keys(line);
- vns.shift();
- vns.forEach((vn) => {
- const camelVN = context.toCamelCase(vn);
- if (key === 'pages' || key === 'blocks') {
- variants[camelVN][key] = variants[camelVN][key] || [];
- if (key === 'pages') variants[camelVN][key].push(new URL(line[vn]).pathname);
- else variants[camelVN][key].push(line[vn]);
- } else {
- variants[camelVN][key] = line[vn];
- }
- });
- });
- config.variants = variants;
- config.variantNames = variantNames;
- return config;
- } catch (e) {
- // eslint-disable-next-line no-console
- console.log('error parsing experiment config:', e, json);
+export async function getResolvedAudiences(pageAudiences, options) {
+ if (!pageAudiences.length || !Object.keys(options.audiences).length) {
+ return null;
}
- return null;
-}
-
-/**
- * Checks if the given config is a valid experimentation configuration.
- * @param {object} config the config to check
- * @returns `true` if it is valid, `false` otherwise
- */
-export function isValidExperimentationConfig(config) {
- if (!config.variantNames
- || !config.variantNames.length
- || !config.variants
- || !Object.values(config.variants).length
- || !Object.values(config.variants).every((v) => (
- typeof v === 'object'
- && !!v.blocks
- && !!v.pages
- && (v.percentageSplit === '' || !!v.percentageSplit)
- ))) {
- return false;
+ // If we have a forced audience set in the query parameters (typically for simulation purposes)
+ // we check if it is applicable
+ const usp = new URLSearchParams(window.location.search);
+ const forcedAudience = usp.has(options.audiencesQueryParameter)
+ ? toClassName(usp.get(options.audiencesQueryParameter))
+ : null;
+ if (forcedAudience) {
+ return pageAudiences.includes(forcedAudience) ? [forcedAudience] : [];
}
- return true;
+
+ // Otherwise, return the list of audiences that are resolved on the page
+ const results = await Promise.all(
+ pageAudiences
+ .map((key) => {
+ if (options.audiences[key] && typeof options.audiences[key] === 'function') {
+ return options.audiences[key]();
+ }
+ return false;
+ }),
+ );
+ return pageAudiences.filter((_, i) => results[i]);
}
/**
@@ -211,124 +273,17 @@ function inferEmptyPercentageSplits(variants) {
if (variantsWithoutPercentage.length) {
const missingPercentage = remainingPercentage / variantsWithoutPercentage.length;
variantsWithoutPercentage.forEach((v) => {
- v.percentageSplit = missingPercentage.toFixed(2);
+ v.percentageSplit = missingPercentage.toFixed(4);
});
}
}
/**
- * Gets experiment config from the metadata.
- *
- * @param {string} experimentId The experiment identifier
- * @param {string} instantExperiment The list of varaints
- * @returns {object} the experiment manifest
- */
-function getConfigForInstantExperiment(
- experimentId,
- instantExperiment,
- pluginOptions,
- context,
-) {
- const audience = context.getMetadata(`${pluginOptions.experimentsMetaTag}-audience`);
- const config = {
- label: `Instant Experiment: ${experimentId}`,
- audiences: audience ? audience.split(',').map(context.toClassName) : [],
- status: context.getMetadata(`${pluginOptions.experimentsMetaTag}-status`) || 'Active',
- startDate: context.getMetadata(`${pluginOptions.experimentsMetaTag}-start-date`),
- endDate: context.getMetadata(`${pluginOptions.experimentsMetaTag}-end-date`),
- id: experimentId,
- variants: {},
- variantNames: [],
- };
-
- const nbOfVariants = Number(instantExperiment);
- const pages = Number.isNaN(nbOfVariants)
- ? instantExperiment.split(',').map((p) => new URL(p.trim(), window.location).pathname)
- : new Array(nbOfVariants).fill(window.location.pathname);
-
- const splitString = context.getMetadata(`${pluginOptions.experimentsMetaTag}-split`);
- const splits = splitString
- // custom split
- ? splitString.split(',').map((i) => parseInt(i, 10) / 100)
- // even split fallback
- : [...new Array(pages.length)].map(() => 1 / (pages.length + 1));
-
- config.variantNames.push('control');
- config.variants.control = {
- percentageSplit: '',
- pages: [window.location.pathname],
- blocks: [],
- label: 'Control',
- };
-
- pages.forEach((page, i) => {
- const vname = `challenger-${i + 1}`;
- config.variantNames.push(vname);
- config.variants[vname] = {
- percentageSplit: `${splits[i].toFixed(2)}`,
- pages: [page],
- blocks: [],
- label: `Challenger ${i + 1}`,
- };
- });
- inferEmptyPercentageSplits(Object.values(config.variants));
- return (config);
-}
-
-/**
- * Gets experiment config from the manifest and transforms it to more easily
- * consumable structure.
- *
- * the manifest consists of two sheets "settings" and "experiences", by default
- *
- * "settings" is applicable to the entire test and contains information
- * like "Audience", "Status" or "Blocks".
- *
- * "experience" hosts the experiences in rows, consisting of:
- * a "Percentage Split", "Label" and a set of "Links".
- *
- *
- * @param {string} experimentId The experiment identifier
- * @param {object} pluginOptions The plugin options
- * @returns {object} containing the experiment manifest
+ * Converts the experiment config to a decision policy
+ * @param {Object} config The experiment config
+ * @returns a decision policy for the experiment config
*/
-async function getConfigForFullExperiment(experimentId, pluginOptions, context) {
- let path;
- if (experimentId.includes(`/${pluginOptions.experimentsConfigFile}`)) {
- path = new URL(experimentId, window.location.origin).href;
- // eslint-disable-next-line no-param-reassign
- [experimentId] = path.split('/').splice(-2, 1);
- } else {
- path = `${pluginOptions.experimentsRoot}/${experimentId}/${pluginOptions.experimentsConfigFile}`;
- }
- try {
- const resp = await fetch(path);
- if (!resp.ok) {
- // eslint-disable-next-line no-console
- console.log('error loading experiment config:', resp);
- return null;
- }
- const json = await resp.json();
- const config = pluginOptions.parser
- ? pluginOptions.parser(json, context)
- : parseExperimentConfig(json, context);
- if (!config) {
- return null;
- }
- config.id = experimentId;
- config.manifest = path;
- config.basePath = `${pluginOptions.experimentsRoot}/${experimentId}`;
- inferEmptyPercentageSplits(Object.values(config.variants));
- config.status = context.getMetadata(`${pluginOptions.experimentsMetaTag}-status`) || config.status;
- return config;
- } catch (e) {
- // eslint-disable-next-line no-console
- console.log(`error loading experiment manifest: ${path}`, e);
- }
- return null;
-}
-
-function getDecisionPolicy(config) {
+function toDecisionPolicy(config) {
const decisionPolicy = {
id: 'content-experimentation-policy',
rootDecisionNodeId: 'n1',
@@ -349,364 +304,610 @@ function getDecisionPolicy(config) {
return decisionPolicy;
}
-async function getConfig(experiment, instantExperiment, pluginOptions, context) {
- const usp = new URLSearchParams(window.location.search);
- const [forcedExperiment, forcedVariant] = usp.has(pluginOptions.experimentsQueryParameter)
- ? usp.get(pluginOptions.experimentsQueryParameter).split('/')
- : [];
+/**
+ * Creates an instance of a modification handler that will be responsible for applying the desired
+ * personalized experience.
+ *
+ * @param {Object} overrides The config overrides
+ * @param {Function} metadataToConfig a function that will handle the parsing of the metadata
+ * @param {Function} getExperienceUrl a function that returns the URL to the experience
+ * @param {Object} pluginOptions the plugin options
+ * @param {Function} cb the callback to handle the final steps
+ * @returns the modification handler
+ */
+function createModificationsHandler(
+ overrides,
+ metadataToConfig,
+ getExperienceUrl,
+ pluginOptions,
+ cb,
+) {
+ return async (el, metadata) => {
+ const config = await metadataToConfig(pluginOptions, metadata, overrides);
+ if (!config) {
+ return null;
+ }
+ const ns = { config, el };
+ const url = await getExperienceUrl(ns.config);
+ let res;
+ if (url && new URL(url, window.location.origin).pathname !== window.location.pathname) {
+ res = await replaceInner(url, el);
+ } else {
+ res = url;
+ }
+ cb(el.tagName === 'MAIN' ? document.body : ns.el, ns.config, res ? url : null);
+ if (res) {
+ ns.servedExperience = url;
+ }
+ return ns;
+ };
+}
- const experimentConfig = instantExperiment
- ? await getConfigForInstantExperiment(experiment, instantExperiment, pluginOptions, context)
- : await getConfigForFullExperiment(experiment, pluginOptions, context);
+/**
+ * Rename plural properties on the object to singular.
+ * @param {Object} obj The object
+ * @param {String[]} props The properties to rename.
+ * @returns the object with plural properties renamed.
+ */
+function depluralizeProps(obj, props = []) {
+ props.forEach((prop) => {
+ if (obj[`${prop}s`]) {
+ obj[prop] = obj[`${prop}s`];
+ delete obj[`${prop}s`];
+ }
+ });
+ return obj;
+}
- // eslint-disable-next-line no-console
- console.debug(experimentConfig);
- if (!experimentConfig) {
- return null;
+/**
+ * Fetch the configuration entries from a JSON manifest.
+ * @param {String} urlString the URL to load
+ * @returns the list of entries that apply to the current page
+ */
+async function getManifestEntriesForCurrentPage(urlString) {
+ try {
+ const url = new URL(urlString, window.location.origin);
+ const response = await fetch(url);
+ const json = await response.json();
+ return json.data
+ .map((entry) => Object.keys(entry).reduce((res, k) => {
+ res[k.toLowerCase()] = entry[k];
+ return res;
+ }, {}))
+ .filter((entry) => (!entry.page && !entry.pages)
+ || entry.page === window.location.pathname
+ || entry.pages === window.location.pathname)
+ .filter((entry) => entry.selector || entry.selectors)
+ .filter((entry) => entry.url || entry.urls)
+ .map((entry) => depluralizeProps(entry, ['page', 'selector', 'url']));
+ } catch (err) {
+ // eslint-disable-next-line no-console
+ console.warn('Cannot apply manifest: ', urlString, err);
}
+ return null;
+}
- const forcedAudience = usp.has(pluginOptions.audiencesQueryParameter)
- ? context.toClassName(usp.get(pluginOptions.audiencesQueryParameter))
- : null;
+/**
+ * Watches the page for injected DOM elements and automatically applies the fragment customizations
+ */
+function watchMutationsAndApplyFragments(
+ ns,
+ scope,
+ entries,
+ aggregator,
+ getExperienceUrl,
+ pluginOptions,
+ metadataToConfig,
+ overrides,
+ cb,
+) {
+ if (!entries.length) {
+ return;
+ }
- experimentConfig.resolvedAudiences = await getResolvedAudiences(
- experimentConfig.audiences.map(context.toClassName),
+ new MutationObserver(async (_, observer) => {
+ // eslint-disable-next-line no-restricted-syntax
+ for (const entry of entries) {
+ // eslint-disable-next-line no-await-in-loop
+ const config = await metadataToConfig(pluginOptions, entry, overrides);
+ if (!config || entry.isApplied) {
+ return;
+ }
+ const el = scope.querySelector(entry.selector);
+ if (!el) {
+ return;
+ }
+ entry.isApplied = true;
+ const fragmentNS = { config, el, type: 'fragment' };
+ // eslint-disable-next-line no-await-in-loop
+ const url = await getExperienceUrl(fragmentNS.config);
+ let res;
+ if (url && new URL(url, window.location.origin).pathname !== window.location.pathname) {
+ // eslint-disable-next-line no-await-in-loop
+ res = await replaceInner(url, el, entry.selector);
+ } else {
+ res = url;
+ }
+ cb(el.tagName === 'MAIN' ? document.body : fragmentNS.el, fragmentNS.config, res ? url : null);
+ if (res) {
+ fragmentNS.servedExperience = url;
+ }
+ debug('fragment', ns, fragmentNS);
+ aggregator.push(fragmentNS);
+ }
+ if (entries.every((entry) => entry.isApplied)) {
+ observer.disconnect();
+ }
+ }).observe(scope, { childList: true, subtree: true });
+}
+
+/**
+ * Apply the page modifications for the specified type.
+ *
+ * @param {String} ns the type of modifications to do
+ * @param {String} paramNS the query parameter namespace
+ * @param {Object} pluginOptions the plugin options
+ * @param {Function} metadataToConfig a function that will handle the parsing of the metadata
+ * @param {Function} manifestToConfig a function that will handle the parsing of the manifest
+ * @param {Function} getExperienceUrl a function that returns the URL to the experience
+ * @param {Function} cb the callback to handle the final steps
+ * @returns an object containing the details of the page modifications that where applied
+ */
+async function applyAllModifications(
+ type,
+ paramNS,
+ pluginOptions,
+ metadataToConfig,
+ manifestToConfig,
+ getExperienceUrl,
+ cb,
+) {
+ const modificationsHandler = createModificationsHandler(
+ getAllQueryParameters(paramNS),
+ metadataToConfig,
+ getExperienceUrl,
pluginOptions,
- context,
- );
- experimentConfig.run = (
- // experiment is active or forced
- (['active', 'on', 'true'].includes(context.toClassName(experimentConfig.status)) || forcedExperiment)
- // experiment has resolved audiences if configured
- && (!experimentConfig.resolvedAudiences || experimentConfig.resolvedAudiences.length)
- // forced audience resolves if defined
- && (!forcedAudience || experimentConfig.audiences.includes(forcedAudience))
- && (!experimentConfig.startDate || new Date(experimentConfig.startDate) <= Date.now())
- && (!experimentConfig.endDate || new Date(experimentConfig.endDate) > Date.now())
+ cb,
);
- window.hlx = window.hlx || {};
- window.hlx.experiment = experimentConfig;
+ const configs = [];
- // eslint-disable-next-line no-console
- console.debug('run', experimentConfig.run, experimentConfig.audiences);
- if (forcedVariant && experimentConfig.variantNames.includes(forcedVariant)) {
- experimentConfig.selectedVariant = forcedVariant;
- } else {
- // eslint-disable-next-line import/extensions
- const { ued } = await import('./ued.js');
- const decision = ued.evaluateDecisionPolicy(getDecisionPolicy(experimentConfig), {});
- experimentConfig.selectedVariant = decision.items[0].id;
+ // Full-page modifications
+ const pageMetadata = getAllMetadata(type);
+ const pageNS = await modificationsHandler(
+ document.querySelector('main'),
+ pageMetadata,
+ );
+ if (pageNS) {
+ pageNS.type = 'page';
+ configs.push(pageNS);
+ debug('page', type, pageNS);
+ }
+
+ // Section-level modifications
+ let sectionMetadata;
+ await Promise.all([...document.querySelectorAll('.section-metadata')]
+ .map(async (sm) => {
+ sectionMetadata = getAllSectionMeta(sm, type);
+ const sectionNS = await modificationsHandler(
+ sm.parentElement,
+ sectionMetadata,
+ );
+ if (sectionNS) {
+ sectionNS.type = 'section';
+ debug('section', type, sectionNS);
+ configs.push(sectionNS);
+ }
+ }));
+
+ // Fragment-level modifications
+ if (pageMetadata.manifest) {
+ let entries = await getManifestEntriesForCurrentPage(pageMetadata.manifest);
+ if (entries) {
+ entries = manifestToConfig(entries);
+ watchMutationsAndApplyFragments(
+ type,
+ document.body,
+ entries,
+ configs,
+ getExperienceUrl,
+ pluginOptions,
+ metadataToConfig,
+ getAllQueryParameters(paramNS),
+ cb,
+ );
+ }
}
- return experimentConfig;
+
+ return configs;
}
-export async function runExperiment(document, options, context) {
- if (isBot()) {
- return false;
- }
+function aggregateEntries(type, allowedMultiValuesProperties) {
+ return (entries) => entries.reduce((aggregator, entry) => {
+ Object.entries(entry).forEach(([key, value]) => {
+ if (!aggregator[key]) {
+ aggregator[key] = value;
+ } else if (aggregator[key] !== value) {
+ if (allowedMultiValuesProperties.includes(key)) {
+ aggregator[key] = [].concat(aggregator[key], value);
+ } else {
+ // eslint-disable-next-line no-console
+ console.warn(`Key "${key}" in the ${type} manifest must be the same for every variant on the page.`);
+ }
+ }
+ });
+ return aggregator;
+ }, {});
+}
- const pluginOptions = { ...DEFAULT_OPTIONS, ...(options || {}) };
- const experiment = context.getMetadata(pluginOptions.experimentsMetaTag);
- if (!experiment) {
- return false;
- }
- const variants = context.getMetadata('instant-experiment')
- || context.getMetadata(`${pluginOptions.experimentsMetaTag}-variants`);
- let experimentConfig;
- try {
- experimentConfig = await getConfig(experiment, variants, pluginOptions, context);
- } catch (err) {
- // eslint-disable-next-line no-console
- console.error('Invalid experiment config.', err);
- }
- if (!experimentConfig || !isValidExperimentationConfig(experimentConfig)) {
- // eslint-disable-next-line no-console
- console.warn('Invalid experiment config. Please review your metadata, sheet and parser.');
- return false;
+/**
+ * Parses the experiment configuration from the metadata
+ */
+async function getExperimentConfig(pluginOptions, metadata, overrides) {
+ const id = toClassName(metadata.value || metadata.experiment);
+ if (!id) {
+ return null;
}
- const usp = new URLSearchParams(window.location.search);
- const forcedVariant = usp.has(pluginOptions.experimentsQueryParameter)
- ? usp.get(pluginOptions.experimentsQueryParameter).split('/')[1]
- : null;
- if (!experimentConfig.run && !forcedVariant) {
- // eslint-disable-next-line no-console
- console.warn('Experiment will not run. It is either not active or its configured audiences are not resolved.');
- return false;
+ let pages = metadata.variants || metadata.url;
+
+ // Backward compatibility
+ if (!pages) {
+ pages = getMetadata('instant-experiment');
}
- // eslint-disable-next-line no-console
- console.debug(`running experiment (${window.hlx.experiment.id}) -> ${window.hlx.experiment.selectedVariant}`);
-
- if (experimentConfig.selectedVariant === experimentConfig.variantNames[0]) {
- document.body.classList.add(`experiment-${context.toClassName(experimentConfig.id)}`);
- document.body.classList.add(`variant-${context.toClassName(experimentConfig.selectedVariant)}`);
- context.sampleRUM('experiment', {
- source: experimentConfig.id,
- target: experimentConfig.selectedVariant,
- });
- return false;
+ if (metadata.audience) {
+ metadata.audiences = metadata.audience;
}
- const { pages } = experimentConfig.variants[experimentConfig.selectedVariant];
+ const nbOfVariants = Number(pages);
+ pages = Number.isNaN(nbOfVariants)
+ ? stringToArray(pages).map((p) => new URL(p.trim(), window.location).pathname)
+ : new Array(nbOfVariants).fill(window.location.pathname);
if (!pages.length) {
- return false;
+ return null;
}
- const currentPath = window.location.pathname;
- const control = experimentConfig.variants[experimentConfig.variantNames[0]];
- const index = control.pages.indexOf(currentPath);
- if (index < 0) {
- return false;
- }
+ const audiences = stringToArray(metadata.audiences).map(toClassName);
- // Fullpage content experiment
- document.body.classList.add(`experiment-${context.toClassName(experimentConfig.id)}`);
- let result;
- if (pages[index] !== currentPath) {
- result = await replaceInner(pages[index], document.querySelector('main'));
- } else {
- result = currentPath;
- }
- experimentConfig.servedExperience = result || currentPath;
- if (!result) {
- // eslint-disable-next-line no-console
- console.debug(`failed to serve variant ${window.hlx.experiment.selectedVariant}. Falling back to ${experimentConfig.variantNames[0]}.`);
- }
- document.body.classList.add(`variant-${context.toClassName(result ? experimentConfig.selectedVariant : experimentConfig.variantNames[0])}`);
- context.sampleRUM('experiment', {
- source: experimentConfig.id,
- target: result ? experimentConfig.selectedVariant : experimentConfig.variantNames[0],
- });
- return result;
-}
+ const splits = metadata.split
+ // custom split
+ ? stringToArray(metadata.split).map((i) => parseFloat(i) / 100)
+ // even split
+ : [...new Array(pages.length)].map(() => 1 / (pages.length + 1));
-export async function runCampaign(document, options, context) {
- if (isBot()) {
- return false;
- }
+ const variantNames = [];
+ variantNames.push('control');
+ stringToArray(getMetadata("variants-name")).forEach((v) => {
+ if (variantNames.length <= pages.length) {
+ variantNames.push(v);
+ } else{
+ console.log(`Variant name "${v}" is ignored: Number of variants names is more than the number of variants`);
+ }
+ });
- const pluginOptions = { ...DEFAULT_OPTIONS, ...options };
- const usp = new URLSearchParams(window.location.search);
- const campaign = (usp.has(pluginOptions.campaignsQueryParameter)
- ? context.toClassName(usp.get(pluginOptions.campaignsQueryParameter))
- : null)
- || (usp.has('utm_campaign') ? context.toClassName(usp.get('utm_campaign')) : null);
- if (!campaign) {
- return false;
- }
+ const variants = {};
+ variants.control = {
+ percentageSplit: '',
+ pages: [window.location.pathname],
+ label: 'Control',
+ };
- let audiences = context.getMetadata(`${pluginOptions.campaignsMetaTagPrefix}-audience`);
- let resolvedAudiences = null;
- if (audiences) {
- audiences = audiences.split(',').map(context.toClassName);
- resolvedAudiences = await getResolvedAudiences(audiences, pluginOptions, context);
- if (!!resolvedAudiences && !resolvedAudiences.length) {
- return false;
+ pages.forEach((page, i) => {
+ const vname =
+ variantNames.length > i + 1
+ ? variantNames[i + 1]
+ : `challenger-${i + 1}`;
+ if (variantNames.length <= i + 1) {
+ variantNames.push(vname);
}
- }
+ variants[vname] = {
+ percentageSplit: `${splits[i].toFixed(4)}`,
+ pages: [page],
+ blocks: [],
+ label: `Challenger ${i + 1}`,
+ };
+ });
+ inferEmptyPercentageSplits(Object.values(variants));
- const allowedCampaigns = context.getAllMetadata(pluginOptions.campaignsMetaTagPrefix);
- if (!Object.keys(allowedCampaigns).includes(campaign)) {
- return false;
- }
+ const resolvedAudiences = await getResolvedAudiences(
+ audiences,
+ pluginOptions,
+ );
- const urlString = allowedCampaigns[campaign];
- if (!urlString) {
- return false;
- }
+ const startDate = metadata.startDate ? new Date(metadata.startDate) : null;
+ const endDate = metadata.endDate ? new Date(metadata.endDate) : null;
+
+ const config = {
+ id,
+ label: metadata.name || `Experiment ${metadata.value || metadata.experiment}`,
+ status: metadata.status || 'active',
+ audiences,
+ endDate,
+ resolvedAudiences,
+ startDate,
+ variants,
+ variantNames,
+ };
+
+ config.run = (
+ // experiment is active or forced
+ (['active', 'on', 'true'].includes(toClassName(config.status)) || overrides.value)
+ // experiment has resolved audiences if configured
+ && (!resolvedAudiences || resolvedAudiences.length)
+ // forced audience resolves if defined
+ && (!overrides.audience || audiences.includes(overrides.audience))
+ && (!startDate || startDate <= Date.now())
+ && (!endDate || endDate > Date.now())
+ );
- window.hlx.campaign = { selectedCampaign: campaign };
- if (resolvedAudiences) {
- window.hlx.campaign.resolvedAudiences = window.hlx.campaign;
+ if (!config.run) {
+ return config;
}
- try {
- const url = new URL(urlString);
- const result = await replaceInner(url.pathname, document.querySelector('main'));
- window.hlx.campaign.servedExperience = result || window.location.pathname;
- if (!result) {
- // eslint-disable-next-line no-console
- console.debug(`failed to serve campaign ${campaign}. Falling back to default content.`);
- }
- document.body.classList.add(`campaign-${campaign}`);
- context.sampleRUM('campaign', {
- source: window.location.href,
- target: result ? campaign : 'default',
- });
- return result;
- } catch (err) {
- // eslint-disable-next-line no-console
- console.error(err);
- return false;
+ const [, forcedVariant] = (Array.isArray(overrides.value)
+ ? overrides.value
+ : stringToArray(overrides.value))
+ .map((value) => value?.split('/'))
+ .find(([experiment]) => toClassName(experiment) === config.id) || [];
+ if (variantNames.includes(toClassName(forcedVariant))) {
+ config.selectedVariant = toClassName(forcedVariant);
+ } else if (overrides.variant && variantNames.includes(overrides.variant)) {
+ config.selectedVariant = toClassName(overrides.variant);
+ } else {
+ // eslint-disable-next-line import/extensions
+ const { ued } = await import('./ued.js');
+ const decision = ued.evaluateDecisionPolicy(toDecisionPolicy(config), {});
+ config.selectedVariant = decision.items[0].id;
}
+
+ return config;
+}
+/**
+ * Parses the campaign manifest.
+ */
+function parseExperimentManifest(entries) {
+ return Object.values(Object.groupBy(
+ entries.map((e) => depluralizeProps(e, ['experiment', 'variant', 'split'])),
+ ({ experiment }) => experiment,
+ )).map(aggregateEntries('experiment', ['split', 'url', 'variant']));
}
-export async function serveAudience(document, options, context) {
- if (isBot()) {
- return false;
+function getUrlFromExperimentConfig(config) {
+ return config.run
+ ? config.variants[config.selectedVariant].pages[0]
+ : null;
+}
+
+async function runExperiment(document, pluginOptions) {
+ return applyAllModifications(
+ pluginOptions.experimentsMetaTagPrefix,
+ pluginOptions.experimentsQueryParameter,
+ pluginOptions,
+ getExperimentConfig,
+ parseExperimentManifest,
+ getUrlFromExperimentConfig,
+ (el, config, result) => {
+ const { id, selectedVariant, variantNames } = config;
+ const variant = result ? selectedVariant : variantNames[0];
+ el.classList.add(`experiment-${toClassName(id)}`);
+ el.classList.add(`variant-${toClassName(variant)}`);
+ window.hlx?.rum?.sampleRUM('experiment', {
+ source: id,
+ target: variant,
+ });
+ document.dispatchEvent(new CustomEvent('aem:experimentation', {
+ detail: {
+ element: el,
+ type: 'experiment',
+ experiment: id,
+ variant,
+ },
+ }));
+ },
+ );
+}
+
+/**
+ * Parses the campaign configuration from the metadata
+ */
+async function getCampaignConfig(pluginOptions, metadata, overrides) {
+ if (!Object.keys(metadata).length || (Object.keys(metadata).length === 1 && metadata.manifest)) {
+ return null;
}
- const pluginOptions = { ...DEFAULT_OPTIONS, ...(options || {}) };
- const configuredAudiences = context.getAllMetadata(pluginOptions.audiencesMetaTagPrefix);
- if (!Object.keys(configuredAudiences).length) {
- return false;
+ // Check UTM parameters
+ let campaign = overrides.value;
+ if (!campaign) {
+ const usp = new URLSearchParams(window.location.search);
+ if (usp.has('utm_campaign')) {
+ campaign = toClassName(usp.get('utm_campaign'));
+ }
+ } else {
+ campaign = toClassName(campaign);
+ }
+
+ if (metadata.audience) {
+ metadata.audiences = metadata.audience;
}
- const audiences = await getResolvedAudiences(
- Object.keys(configuredAudiences).map(context.toClassName),
+ const audiences = stringToArray(metadata.audiences).map(toClassName);
+ const resolvedAudiences = await getResolvedAudiences(
+ audiences,
pluginOptions,
- context,
);
- if (!audiences || !audiences.length) {
- return false;
+ if (resolvedAudiences && !resolvedAudiences.length) {
+ return null;
}
- const usp = new URLSearchParams(window.location.search);
- const forcedAudience = usp.has(pluginOptions.audiencesQueryParameter)
- ? context.toClassName(usp.get(pluginOptions.audiencesQueryParameter))
- : null;
-
- const selectedAudience = forcedAudience || audiences[0];
- const urlString = configuredAudiences[selectedAudience];
- if (!urlString) {
- return false;
- }
+ const configuredCampaigns = Object.fromEntries(Object.entries(metadata.campaigns || metadata)
+ .filter(([key]) => !['audience', 'audiences'].includes(key)));
- window.hlx.audience = { selectedAudience };
+ return {
+ audiences,
+ configuredCampaigns,
+ resolvedAudiences,
+ selectedCampaign: campaign && (metadata.campaigns || metadata)[campaign]
+ ? campaign
+ : null,
+ };
+}
- try {
- const url = new URL(urlString);
- const result = await replaceInner(url.pathname, document.querySelector('main'));
- window.hlx.audience.servedExperience = result || window.location.pathname;
- if (!result) {
- // eslint-disable-next-line no-console
- console.debug(`failed to serve audience ${selectedAudience}. Falling back to default content.`);
- }
- document.body.classList.add(audiences.map((audience) => `audience-${audience}`));
- context.sampleRUM('audiences', {
- source: window.location.href,
- target: result ? forcedAudience || audiences.join(',') : 'default',
+/**
+ * Parses the campaign manifest.
+ */
+function parseCampaignManifest(entries) {
+ return Object.values(Object.groupBy(
+ entries.map((e) => depluralizeProps(e, ['campaign'])),
+ ({ selector }) => selector,
+ ))
+ .map(aggregateEntries('campaign', ['campaign', 'url']))
+ .map((e) => {
+ const campaigns = e.campaign;
+ delete e.campaign;
+ e.campaigns = {};
+ campaigns.forEach((a, i) => {
+ e.campaigns[toClassName(a)] = e.url[i];
+ });
+ delete e.url;
+ return e;
});
- return result;
- } catch (err) {
- // eslint-disable-next-line no-console
- console.error(err);
- return false;
- }
}
-window.hlx.patchBlockConfig?.push((config) => {
- const { experiment } = window.hlx;
-
- // No experiment is running
- if (!experiment || !experiment.run) {
- return config;
- }
+function getUrlFromCampaignConfig(config) {
+ return config.selectedCampaign
+ ? config.configuredCampaigns[config.selectedCampaign]
+ : null;
+}
- // The current experiment does not modify the block
- if (experiment.selectedVariant === experiment.variantNames[0]
- || !experiment.variants[experiment.variantNames[0]].blocks
- || !experiment.variants[experiment.variantNames[0]].blocks.includes(config.blockName)) {
- return config;
- }
+async function runCampaign(document, pluginOptions) {
+ return applyAllModifications(
+ pluginOptions.campaignsMetaTagPrefix,
+ pluginOptions.campaignsQueryParameter,
+ pluginOptions,
+ getCampaignConfig,
+ parseCampaignManifest,
+ getUrlFromCampaignConfig,
+ (el, config, result) => {
+ const { selectedCampaign = 'default' } = config;
+ const campaign = result ? toClassName(selectedCampaign) : 'default';
+ el.classList.add(`campaign-${campaign}`);
+ window.hlx?.rum?.sampleRUM('campaign', {
+ source: el.className,
+ target: campaign,
+ });
+ document.dispatchEvent(new CustomEvent('aem:experimentation', {
+ detail: {
+ element: el,
+ type: 'campaign',
+ campaign,
+ },
+ }));
+ },
+ );
+}
- // The current experiment does not modify the block code
- const variant = experiment.variants[experiment.selectedVariant];
- if (!variant.blocks.length) {
- return config;
+/**
+ * Parses the audience configuration from the metadata
+ */
+async function getAudienceConfig(pluginOptions, metadata, overrides) {
+ if (!Object.keys(metadata).length || (Object.keys(metadata).length === 1 && metadata.manifest)) {
+ return null;
}
- let index = experiment.variants[experiment.variantNames[0]].blocks.indexOf('');
- if (index < 0) {
- index = experiment.variants[experiment.variantNames[0]].blocks.indexOf(config.blockName);
- }
- if (index < 0) {
- index = experiment.variants[experiment.variantNames[0]].blocks.indexOf(`/blocks/${config.blockName}`);
- }
- if (index < 0) {
- return config;
+ const configuredAudiencesName = Object.keys(metadata.audiences || metadata).map(toClassName);
+ const resolvedAudiences = await getResolvedAudiences(
+ configuredAudiencesName,
+ pluginOptions,
+ );
+ if (resolvedAudiences && !resolvedAudiences.length) {
+ return false;
}
- let origin = '';
- let path;
- if (/^https?:\/\//.test(variant.blocks[index])) {
- const url = new URL(variant.blocks[index]);
- // Experimenting from a different branch
- if (url.origin !== window.location.origin) {
- origin = url.origin;
- }
- // Experimenting from a block path
- if (url.pathname !== '/') {
- path = url.pathname;
- } else {
- path = `/blocks/${config.blockName}`;
- }
- } else { // Experimenting from a different branch on the same branch
- path = `/blocks/${variant.blocks[index]}`;
- }
- if (!origin && !path) {
- return config;
- }
+ const selectedAudience = overrides.audience || resolvedAudiences[0];
- const { codeBasePath } = window.hlx;
return {
- ...config,
- cssPath: `${origin}${codeBasePath}${path}/${config.blockName}.css`,
- jsPath: `${origin}${codeBasePath}${path}/${config.blockName}.js`,
- };
-});
-
-let isAdjusted = false;
-function adjustedRumSamplingRate(checkpoint, options, context) {
- const pluginOptions = { ...DEFAULT_OPTIONS, ...(options || {}) };
- return (data) => {
- if (!window.hlx.rum.isSelected && !isAdjusted) {
- isAdjusted = true;
- // adjust sampling rate based on project config …
- window.hlx.rum.weight = Math.min(
- window.hlx.rum.weight,
- // … but limit it to the 10% sampling at max to avoid losing anonymization
- // and reduce burden on the backend
- Math.max(pluginOptions.rumSamplingRate, MAX_SAMPLING_RATE),
- );
- window.hlx.rum.isSelected = (window.hlx.rum.random * window.hlx.rum.weight < 1);
- if (window.hlx.rum.isSelected) {
- context.sampleRUM(checkpoint, data);
- }
- }
- return true;
+ configuredAudiences: metadata.audiences || metadata,
+ resolvedAudiences,
+ selectedAudience,
};
}
-export async function loadEager(document, options, context) {
- context.sampleRUM.always.on('audiences', adjustedRumSamplingRate('audiences', options, context));
- context.sampleRUM.always.on('campaign', adjustedRumSamplingRate('campaign', options, context));
- context.sampleRUM.always.on('experiment', adjustedRumSamplingRate('experiment', options, context));
- let res = await runCampaign(document, options, context);
- if (!res) {
- res = await runExperiment(document, options, context);
- }
- if (!res) {
- res = await serveAudience(document, options, context);
- }
+/**
+ * Parses the audience manifest.
+ */
+function parseAudienceManifest(entries) {
+ return Object.values(Object.groupBy(
+ entries.map((e) => depluralizeProps(e, ['audience'])),
+ ({ selector }) => selector,
+ ))
+ .map(aggregateEntries('audience', ['audience', 'url']))
+ .map((e) => {
+ const audiences = e.audience;
+ delete e.audience;
+ e.audiences = {};
+ audiences.forEach((a, i) => {
+ e.audiences[toClassName(a)] = e.url[i];
+ });
+ delete e.url;
+ return e;
+ });
}
-export async function loadLazy(document, options, context) {
- const pluginOptions = {
- ...DEFAULT_OPTIONS,
- ...(options || {}),
- };
+function getUrlFromAudienceConfig(config) {
+ return config.selectedAudience
+ ? config.configuredAudiences[config.selectedAudience]
+ : null;
+}
+
+async function serveAudience(document, pluginOptions) {
+ return applyAllModifications(
+ pluginOptions.audiencesMetaTagPrefix,
+ pluginOptions.audiencesQueryParameter,
+ pluginOptions,
+ getAudienceConfig,
+ parseAudienceManifest,
+ getUrlFromAudienceConfig,
+ (el, config, result) => {
+ const { selectedAudience = 'default' } = config;
+ const audience = result ? toClassName(selectedAudience) : 'default';
+ el.classList.add(`audience-${audience}`);
+ window.hlx?.rum?.sampleRUM('audience', {
+ source: el.className,
+ target: audience,
+ });
+ document.dispatchEvent(new CustomEvent('aem:experimentation', {
+ detail: {
+ element: el,
+ type: 'audience',
+ audience,
+ },
+ }));
+ },
+ );
+}
+
+export async function loadEager(document, options = {}) {
+ const pluginOptions = { ...DEFAULT_OPTIONS, ...options };
+ setDebugMode(window.location, pluginOptions);
+
+ const ns = window.aem || window.hlx || {};
+ ns.audiences = await serveAudience(document, pluginOptions);
+ ns.experiments = await runExperiment(document, pluginOptions);
+ ns.campaigns = await runCampaign(document, pluginOptions);
+
+ // Backward compatibility
+ ns.experiment = ns.experiments.find((e) => e.type === 'page');
+ ns.audience = ns.audiences.find((e) => e.type === 'page');
+ ns.campaign = ns.campaigns.find((e) => e.type === 'page');
+}
+
+export async function loadLazy(document, options = {}) {
+ const pluginOptions = { ...DEFAULT_OPTIONS, ...options };
// do not show the experimentation pill on prod domains
- if (window.location.hostname.endsWith('.live')
- || (typeof options.isProd === 'function' && options.isProd())
- || (options.prodHost
- && (options.prodHost === window.location.host
- || options.prodHost === window.location.hostname
- || options.prodHost === window.location.origin))) {
+ if (!isDebugEnabled) {
return;
}
// eslint-disable-next-line import/no-cycle
const preview = await import('./preview.js');
- preview.default(document, pluginOptions, { ...context, getResolvedAudiences });
+ preview.default(document, pluginOptions);
}
diff --git a/plugins/experimentation/src/preview.css b/plugins/experimentation/src/preview.css
index 9b02fbd7..3257e95b 100644
--- a/plugins/experimentation/src/preview.css
+++ b/plugins/experimentation/src/preview.css
@@ -24,7 +24,7 @@
}
.hlx-preview-overlay {
- z-index: 99;
+ z-index: 99999;
position: fixed;
color: #eee;
font-size: 1rem;
@@ -104,9 +104,14 @@
.hlx-popup {
position: absolute;
+ display: grid;
+ grid-template:
+ "header" min-content
+ "content" 1fr;
bottom: 6.5em;
left: 50%;
transform: translateX(-50%);
+ max-height: calc(100vh - 100px - var(--nav-height, 100px));
max-width: calc(100vw - 2em);
min-width: calc(300px - 2em);
background-color: #444;
@@ -128,6 +133,7 @@
.hlx-popup-header {
display: grid;
+ grid-area: header;
grid-template:
"label actions"
"description actions"
@@ -137,6 +143,13 @@
padding: 24px 16px;
}
+.hlx-popup-items {
+ overflow-y: auto;
+ grid-area: content;
+ scrollbar-gutter: stable;
+ scrollbar-width: thin;
+}
+
.hlx-popup-header-label {
grid-area: label;
}
@@ -174,7 +187,7 @@
height: 0;
position: absolute;
border-left: 15px solid transparent;
- border-right: 15px solid transparent;
+ border-right: 15px solid transparent;
border-top: 15px solid #444;
bottom: -15px;
right: 50%;
@@ -198,13 +211,13 @@
.hlx-popup-item {
display: grid;
grid-template:
- "label actions"
+ "label actions"
"description actions"
/ 1fr min-content;
margin: 1em;
padding: 1em;
border-radius: 1em;
- gap: 1em;
+ gap: .5em 1em;
}
.hlx-popup-item-label {
diff --git a/plugins/experimentation/src/preview.js b/plugins/experimentation/src/preview.js
index 5c871eb8..e69ca6c5 100644
--- a/plugins/experimentation/src/preview.js
+++ b/plugins/experimentation/src/preview.js
@@ -9,6 +9,12 @@
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
+// eslint-disable-next-line import/no-cycle
+import {
+ debug,
+ getMetadata,
+ toClassName,
+} from './index.js';
const DOMAIN_KEY_NAME = 'aem-domainkey';
@@ -17,7 +23,7 @@ class AemExperimentationBar extends HTMLElement {
// Create a shadow root
const shadow = this.attachShadow({ mode: 'open' });
- const cssPath = new URL(new Error().stack.split('\n')[2].match(/[a-z]+:[^:]+/)[0]).pathname.replace('preview.js', 'preview.css');
+ const cssPath = new URL(new Error().stack.split('\n')[2].match(/[a-z]+?:\/\/.*?\/[^:]+/)[0]).pathname.replace('preview.js', 'preview.css');
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = cssPath;
@@ -25,15 +31,26 @@ class AemExperimentationBar extends HTMLElement {
shadow.querySelector('.hlx-preview-overlay').removeAttribute('hidden');
};
shadow.append(link);
+ shadow.append(link);
const el = document.createElement('div');
el.className = 'hlx-preview-overlay';
- el.setAttribute('hidden', true);
shadow.append(el);
}
}
customElements.define('aem-experimentation-bar', AemExperimentationBar);
+function watchForAddedExperiences(ns, cb) {
+ let { length } = ns;
+ window.setInterval(() => {
+ if (length !== ns.length) {
+ const diff = length - ns.length;
+ length = ns.length;
+ ns.slice(diff).map((c) => cb(c));
+ }
+ }, 1000);
+}
+
function createPreviewOverlay() {
const overlay = document.createElement('aem-experimentation-bar');
return overlay;
@@ -43,7 +60,19 @@ function getOverlay() {
let overlay = document.querySelector('aem-experimentation-bar')?.shadowRoot.children[1];
if (!overlay) {
const el = createPreviewOverlay();
- document.body.append(el);
+ const style = document.createElement('style');
+ style.textContent = `
+ .hlx-highlight {
+ --highlight-size: .5rem;
+
+ outline-color: #888;
+ outline-offset: calc(-1 * var(--highlight-size));
+ outline-style: dashed;
+ outline-width: var(--highlight-size);
+ background-color: #8882;
+ }`;
+ el.prepend(style);
+ document.body.prepend(el);
[, overlay] = el.shadowRoot.children;
}
return overlay;
@@ -107,14 +136,25 @@ function createPopupDialog(header, items = []) {
return popup;
}
-function createPopupButton(label, header, items) {
+function createPopupButton(label, header, items, eventListeners = {}) {
const button = createButton(label);
const popup = createPopupDialog(header, items);
button.innerHTML += '';
button.append(popup);
- button.addEventListener('click', () => {
+ button.addEventListener('click', (ev) => {
+ if (ev.target.closest('.hlx-popup')) {
+ return;
+ }
+ getOverlay().querySelectorAll('.hlx-badge .hlx-popup:not(.hlx-hidden)').forEach((el) => {
+ if (el !== popup) {
+ el.classList.toggle('hlx-hidden', true);
+ }
+ });
popup.classList.toggle('hlx-hidden');
});
+ Object.entries(eventListeners).forEach(([evt, listener]) => {
+ button.addEventListener(evt, listener);
+ });
return button;
}
@@ -134,7 +174,7 @@ function createToggleButton(label) {
return button;
}
-const percentformat = new Intl.NumberFormat('en-US', { style: 'percent', maximumSignificantDigits: 2 });
+const percentformat = new Intl.NumberFormat('en-US', { style: 'percent', maximumSignificantDigits: 3 });
const countformat = new Intl.NumberFormat('en-US', { maximumSignificantDigits: 2 });
const significanceformat = {
format: (value) => {
@@ -205,6 +245,7 @@ async function fetchRumData(experiment, options) {
}
resultsURL.searchParams.set('domainkey', options.domainKey);
resultsURL.searchParams.set('experiment', experiment);
+ resultsURL.searchParams.set('conversioncheckpoint', options.conversionName);
const response = await fetch(resultsURL.href);
if (!response.ok) {
@@ -285,7 +326,7 @@ async function fetchRumData(experiment, options) {
function populatePerformanceMetrics(div, config, {
richVariants, totals, variantsAsNums, winner,
-}) {
+}, conversionName) {
// add summary
const summary = div.querySelector('.hlx-info');
summary.innerHTML = `Showing results for ${bigcountformat.format(totals.total_experimentations)} visits and ${bigcountformat.format(totals.total_conversions)} conversions: `;
@@ -301,10 +342,10 @@ function populatePerformanceMetrics(div, config, {
// add traffic allocation to control and each variant
config.variantNames.forEach((variantName, index) => {
- const variantDiv = document.querySelectorAll('.hlx-popup-item')[index];
+ const variantDiv = getOverlay().querySelectorAll('.hlx-popup-item')[index];
const percentage = variantDiv.querySelector('.percentage');
percentage.innerHTML = `
- ${bigcountformat.format(richVariants[variantName].variant_conversions)} clicks /
+ ${bigcountformat.format(richVariants[variantName].variant_conversions)} ${conversionName} events /
${bigcountformat.format(richVariants[variantName].variant_experimentations)} visits
(${percentformat.format(richVariants[variantName].variant_experimentations / totals.total_experimentations)} split)
`;
@@ -312,11 +353,11 @@ function populatePerformanceMetrics(div, config, {
// add click rate and significance to each variant
variantsAsNums.forEach((result) => {
- const variant = document.querySelectorAll('.hlx-popup-item')[config.variantNames.indexOf(result.variant)];
+ const variant = getOverlay().querySelectorAll('.hlx-popup-item')[config.variantNames.indexOf(result.variant)];
if (variant) {
const performance = variant.querySelector('.performance');
performance.innerHTML = `
- click rate: ${percentformat.format(result.variant_conversion_rate)}
+ ${conversionName} conversion rate: ${percentformat.format(result.variant_conversion_rate)}
vs. ${percentformat.format(result.control_conversion_rate)}
${significanceformat.format(result.p_value)}
`;
@@ -328,16 +369,18 @@ function populatePerformanceMetrics(div, config, {
* Create Badge if a Page is enlisted in a AEM Experiment
* @return {Object} returns a badge or empty string
*/
-async function decorateExperimentPill(overlay, options, context) {
- const config = window?.hlx?.experiment;
- const experiment = context.toClassName(context.getMetadata(options.experimentsMetaTag));
- if (!experiment || !config) {
+async function decorateExperimentPill({ el, config }, container, options) {
+ if (!config) {
return;
}
// eslint-disable-next-line no-console
- console.log('preview experiment', experiment);
+ debug('preview experiment', config.id);
const domainKey = window.localStorage.getItem(DOMAIN_KEY_NAME);
+ const conversionName = (el.tagName === 'MAIN'
+ ? toClassName(getMetadata('conversion-name'))
+ : el.dataset.conversionName
+ ) || 'click';
const pill = createPopupButton(
`Experiment: ${config.id}`,
{
@@ -348,8 +391,8 @@ async function decorateExperimentPill(overlay, options, context) {
${config.resolvedAudiences ? ', ' : ''}
${config.resolvedAudiences && config.resolvedAudiences.length ? config.resolvedAudiences[0] : ''}
${config.resolvedAudiences && !config.resolvedAudiences.length ? 'No audience resolved' : ''}
- ${config.variants[config.variantNames[0]].blocks.length ? ', Blocks: ' : ''}
- ${config.variants[config.variantNames[0]].blocks.join(',')}
+ ${config.variants[config.variantNames[0]].blocks?.length ? ', Blocks: ' : ''}
+ ${config.variants[config.variantNames[0]].blocks?.join(',') || ''}
How is it going?
`,
actions: [
@@ -364,14 +407,14 @@ async function decorateExperimentPill(overlay, options, context) {
);
if (key && key.match(/[a-f0-9-]+/)) {
window.localStorage.setItem(DOMAIN_KEY_NAME, key);
- const performanceMetrics = await fetchRumData(experiment, {
+ const performanceMetrics = await fetchRumData(config.id, {
...options,
domainKey: key,
});
if (performanceMetrics === null) {
return;
}
- populatePerformanceMetrics(pill, config, performanceMetrics);
+ populatePerformanceMetrics(pill, config, performanceMetrics, conversionName);
} else if (key === '') {
window.localStorage.removeItem(DOMAIN_KEY_NAME);
}
@@ -379,18 +422,41 @@ async function decorateExperimentPill(overlay, options, context) {
},
],
},
- config.variantNames.map((vname) => createVariant(experiment, vname, config, options)),
+ config.variantNames.map((vname) => createVariant(config.id, vname, config, options)),
+ {
+ click: (ev) => {
+ if (!ev.target.querySelector('.hlx-hidden')) {
+ el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
+ }
+ },
+ mouseenter: () => { el.classList.add('hlx-highlight'); },
+ mouseleave: () => {
+ document.querySelectorAll('.hlx-highlight')
+ .forEach((e) => e.classList.remove('hlx-highlight'));
+ },
+ },
);
if (config.run) {
- pill.classList.add(`is-${context.toClassName(config.status)}`);
+ pill.classList.add(`is-${toClassName(config.status)}`);
}
- overlay.append(pill);
-
- const performanceMetrics = await fetchRumData(experiment, { ...options, domainKey });
+ container.append(pill);
+ const performanceMetrics = await fetchRumData(config.id, {
+ ...options, conversionName, domainKey,
+ });
if (performanceMetrics === null) {
return;
}
- populatePerformanceMetrics(pill, config, performanceMetrics);
+ populatePerformanceMetrics(pill, config, performanceMetrics, conversionName);
+}
+
+async function decorateExperimentPills(container, options) {
+ const ns = window.aem || window.hlx;
+ if (!ns?.experiments) {
+ return null;
+ }
+
+ watchForAddedExperiences(ns.experiments, (c) => decorateExperimentPill(c, container, options));
+ return Promise.all(ns.experiments.map((c) => decorateExperimentPill(c, container, options)));
}
function createCampaign(campaign, isSelected, options) {
@@ -412,53 +478,64 @@ function createCampaign(campaign, isSelected, options) {
* Create Badge if a Page is enlisted in a AEM Campaign
* @return {Object} returns a badge or empty string
*/
-async function decorateCampaignPill(overlay, options, context) {
- const campaigns = context.getAllMetadata(options.campaignsMetaTagPrefix);
- if (!Object.keys(campaigns).length) {
+async function decorateCampaignPill({ el, config }, container, options) {
+ if (!config) {
return;
}
-
- const usp = new URLSearchParams(window.location.search);
- const forcedAudience = usp.has(options.audiencesQueryParameter)
- ? context.toClassName(usp.get(options.audiencesQueryParameter))
- : null;
- const audiences = campaigns.audience?.split(',').map(context.toClassName) || [];
- const resolvedAudiences = await context.getResolvedAudiences(audiences, options);
- const isActive = forcedAudience
- ? audiences.includes(forcedAudience)
- : (!resolvedAudiences || !!resolvedAudiences.length);
- const campaign = (usp.has(options.campaignsQueryParameter)
- ? context.toClassName(usp.get(options.campaignsQueryParameter))
- : null)
- || (usp.has('utm_campaign') ? context.toClassName(usp.get('utm_campaign')) : null);
const pill = createPopupButton(
- `Campaign: ${campaign || 'default'}`,
+ `Campaign: ${config.selectedCampaign || 'default'}`,
{
label: 'Campaigns on this page:',
description: `
- ${audiences.length && resolvedAudiences?.length ? `Audience: ${resolvedAudiences[0]}` : ''}
- ${audiences.length && !resolvedAudiences?.length ? 'No audience resolved' : ''}
- ${!audiences.length || !resolvedAudiences ? 'No audience configured' : ''}
+ ${config.audiences.length && config.resolvedAudiences?.length ? `Audience: ${config.resolvedAudiences[0]}` : ''}
+ ${config.audiences.length && !config.resolvedAudiences?.length ? 'No audience resolved' : ''}
+ ${!config.audiences.length || !config.resolvedAudiences ? 'No audience configured' : ''}
`,
},
[
- createCampaign('default', !campaign || !isActive, options),
- ...Object.keys(campaigns)
+ createCampaign('default', !config.selectedCampaign || config.selectedCampaign === 'default', options),
+ ...Object.keys(config.configuredCampaigns)
.filter((c) => c !== 'audience')
- .map((c) => createCampaign(c, isActive && context.toClassName(campaign) === c, options)),
+ .map((c) => createCampaign(c, config.selectedCampaign === c, options)),
],
+ {
+ click: (ev) => {
+ if (!ev.target.querySelector('.hlx-hidden')) {
+ el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
+ }
+ },
+ mouseenter: () => { el.classList.add('hlx-highlight'); },
+ mouseleave: () => {
+ document.querySelectorAll('.hlx-highlight')
+ .forEach((e) => e.classList.remove('hlx-highlight'));
+ },
+ },
);
- if (campaign && isActive) {
+ if (config.selectedCampaign) {
pill.classList.add('is-active');
}
- overlay.append(pill);
+ container.append(pill);
+}
+
+async function decorateCampaignPills(container, options) {
+ const ns = window.aem || window.hlx;
+ if (!ns?.campaigns) {
+ return null;
+ }
+
+ watchForAddedExperiences(ns.campaigns, (c) => decorateCampaignPill(c, container, options));
+ return Promise.all(ns.campaigns.map((c) => decorateCampaignPill(c, container, options)));
}
function createAudience(audience, isSelected, options) {
const url = new URL(window.location.href);
- url.searchParams.set(options.audiencesQueryParameter, audience);
+ if (audience !== 'default') {
+ url.searchParams.set(options.audiencesQueryParameter, audience);
+ } else {
+ url.searchParams.delete(options.audiencesQueryParameter);
+ }
return {
label: `${audience}
`,
@@ -471,46 +548,67 @@ function createAudience(audience, isSelected, options) {
* Create Badge if a Page is enlisted in a AEM Audiences
* @return {Object} returns a badge or empty string
*/
-async function decorateAudiencesPill(overlay, options, context) {
- const audiences = context.getAllMetadata(options.audiencesMetaTagPrefix);
- if (!Object.keys(audiences).length || !Object.keys(options.audiences).length) {
+async function decorateAudiencesPill({ el, config }, container, options) {
+ if (!config) {
+ return;
+ }
+ const configuredAudienceNames = Object.keys(config.configuredAudiences);
+ if (!Object.keys(config.configuredAudiences).length || !Object.keys(options.audiences).length) {
return;
}
- const resolvedAudiences = await context.getResolvedAudiences(
- Object.keys(audiences),
- options,
- context,
- );
const pill = createPopupButton(
- 'Audiences',
+ `Audience: ${config.selectedAudience || 'default'}`,
{
label: 'Audiences for this page:',
},
[
- createAudience('default', !resolvedAudiences.length || resolvedAudiences[0] === 'default', options),
- ...Object.keys(audiences)
+ createAudience('default', !config.selectedAudience || config.selectedAudience === 'default', options),
+ ...configuredAudienceNames
.filter((a) => a !== 'audience')
- .map((a) => createAudience(a, resolvedAudiences && resolvedAudiences[0] === a, options)),
+ .map((a) => createAudience(a, config.selectedAudience === a, options)),
],
+ {
+ click: (ev) => {
+ if (!ev.target.querySelector('.hlx-hidden')) {
+ el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
+ }
+ },
+ mouseenter: () => { el.classList.add('hlx-highlight'); },
+ mouseleave: () => {
+ document.querySelectorAll('.hlx-highlight')
+ .forEach((e) => e.classList.remove('hlx-highlight'));
+ },
+ },
);
- if (resolvedAudiences.length) {
+ if (config.selectedAudience) {
pill.classList.add('is-active');
}
- overlay.append(pill);
+ container.append(pill);
+}
+
+async function decorateAudiencesPills(container, options) {
+ const ns = window.aem || window.hlx;
+ if (!ns?.audiences) {
+ return null;
+ }
+
+ watchForAddedExperiences(ns.audiences, (c) => decorateAudiencesPill(c, container, options));
+ return Promise.all(ns.audiences.map((c) => decorateAudiencesPill(c, container, options)));
}
/**
* Decorates Preview mode badges and overlays
* @return {Object} returns a badge or empty string
*/
-export default async function decoratePreviewMode(document, options, context) {
+export default async function decoratePreviewMode(document, options) {
try {
- const overlay = getOverlay(options);
- await decorateAudiencesPill(overlay, options, context);
- await decorateCampaignPill(overlay, options, context);
- await decorateExperimentPill(overlay, options, context);
+ const overlay = getOverlay();
+
+ await decorateAudiencesPills(overlay, options);
+ await decorateCampaignPills(overlay, options);
+ await decorateExperimentPills(overlay, options);
} catch (e) {
// eslint-disable-next-line no-console
console.log(e);
diff --git a/plugins/experimentation/src/ued.js b/plugins/experimentation/src/ued.js
index d28e91c3..4d4e3a39 100644
--- a/plugins/experimentation/src/ued.js
+++ b/plugins/experimentation/src/ued.js
@@ -9,6 +9,7 @@
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
+/* eslint-disable */
var storage = window.sessionStorage;
diff --git a/plugins/experimentation/tests/audiences.test.js b/plugins/experimentation/tests/audiences.test.js
new file mode 100644
index 00000000..08e4b436
--- /dev/null
+++ b/plugins/experimentation/tests/audiences.test.js
@@ -0,0 +1,194 @@
+/* eslint-disable import/no-extraneous-dependencies */
+import { test, expect } from '@playwright/test';
+import { track } from './coverage.js';
+import { goToAndRunAudience, waitForDomEvent } from './utils.js';
+
+track(test);
+
+test.describe('Page-level audiences', () => {
+ test('Replaces the page content with the variant.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/page-level');
+ expect(await page.locator('main').textContent()).toContain('Hello v1!');
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/page-level--async');
+ expect(await page.locator('main').textContent()).toContain('Hello v2!');
+ });
+
+ test('Sets a class on the body for the main resolved audience.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/page-level');
+ expect(await page.locator('body').getAttribute('class')).not.toContain('audience-default');
+ expect(await page.locator('body').getAttribute('class')).toContain('audience-foo');
+ expect(await page.locator('body').getAttribute('class')).not.toContain('audience-bar');
+ });
+
+ test('Ignores empty audiences.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/page-level--empty');
+ expect(await page.locator('main').textContent()).toContain('Hello World!');
+ expect(await page.locator('body').getAttribute('class')).toContain('audience-default');
+ expect(await page.locator('body').getAttribute('class')).not.toContain('audience-foo');
+ expect(await page.locator('body').getAttribute('class')).not.toContain('audience-bar');
+ });
+
+ test('Controls the audience shown via query parameters.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/page-level?audience=foo');
+ expect(await page.locator('main').textContent()).toContain('Hello v1!');
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/page-level?audience=bar');
+ expect(await page.locator('main').textContent()).toContain('Hello v2!');
+ });
+
+ test('Ignores invalid audiences.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/page-level--invalid');
+ expect(await page.locator('main').textContent()).toContain('Hello v2!');
+ });
+
+ test('Ignores invalid audience references in the query parameters.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/page-level?audience=baz');
+ expect(await page.locator('main').textContent()).toContain('Hello World!');
+ });
+
+ test('Ignores invalid variant urls.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/page-level--invalid-url');
+ expect(await page.locator('main').textContent()).toContain('Hello World!');
+ });
+
+ test('Tracks the audience in RUM.', async ({ page }) => {
+ await page.addInitScript(() => {
+ window.rumCalls = [];
+ window.hlx = { rum: { sampleRUM: (...args) => window.rumCalls.push(args) } };
+ });
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/page-level');
+ expect(await page.evaluate(() => window.rumCalls)).toContainEqual([
+ 'audience',
+ expect.objectContaining({
+ source: 'audience-foo',
+ target: 'foo',
+ }),
+ ]);
+ });
+
+ test('Exposes the audiences in a JS API.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/page-level');
+ expect(await page.evaluate(() => window.hlx.audiences)).toContainEqual(
+ expect.objectContaining({
+ type: 'page',
+ config: expect.objectContaining({
+ configuredAudiences: {
+ foo: '/tests/fixtures/audiences/variant-1',
+ bar: '/tests/fixtures/audiences/variant-2',
+ },
+ resolvedAudiences: ['foo', 'bar'],
+ selectedAudience: 'foo',
+ }),
+ servedExperience: '/tests/fixtures/audiences/variant-1',
+ }),
+ );
+ });
+
+ test('triggers a DOM event with the audience detail', async ({ page }) => {
+ const fn = await waitForDomEvent(page, 'aem:experimentation');
+ await page.goto('/tests/fixtures/audiences/page-level');
+ expect(await page.evaluate(fn)).toEqual({
+ type: 'audience',
+ element: await page.evaluate(() => document.body),
+ audience: 'foo',
+ });
+ });
+});
+
+test.describe('Section-level audiences', () => {
+ test('Replaces the section content with the variant.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/section-level');
+ expect(await page.locator('main>div').textContent()).toContain('Hello v2!');
+ });
+
+ test('Sets classes on the section for the audience.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/section-level');
+ expect(await page.locator('main>div').getAttribute('class')).toContain('audience-bar');
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/section-level?audience=foo');
+ expect(await page.locator('main>div').getAttribute('class')).toContain('audience-foo');
+ });
+
+ test('Exposes the audiences in a JS API.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/section-level');
+ expect(await page.evaluate(() => window.hlx.audiences)).toContainEqual(
+ expect.objectContaining({
+ type: 'section',
+ config: expect.objectContaining({
+ configuredAudiences: {
+ foo: `${await page.evaluate(() => window.location.origin)}/tests/fixtures/audiences/variant-1`,
+ bar: '/tests/fixtures/audiences/variant-2',
+ },
+ resolvedAudiences: ['bar'],
+ selectedAudience: 'bar',
+ }),
+ servedExperience: '/tests/fixtures/audiences/variant-2',
+ }),
+ );
+ });
+
+ test('triggers a DOM event with the audience detail', async ({ page }) => {
+ const fn = await waitForDomEvent(page, 'aem:experimentation');
+ await page.goto('/tests/fixtures/audiences/section-level');
+ expect(await page.evaluate(fn)).toEqual({
+ type: 'audience',
+ element: await page.evaluate(() => document.querySelector('.section')),
+ audience: 'bar',
+ });
+ });
+});
+
+test.describe('Fragment-level audiences', () => {
+ test('Replaces the fragment content with the variant.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/fragment-level');
+ expect(await page.locator('.fragment').textContent()).toContain('Hello v1!');
+ });
+
+ test('Supports plural format for manifest keys.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/fragment-level--alt');
+ expect(await page.locator('.fragment').textContent()).toContain('Hello v1!');
+ });
+
+ test('Ignores invalid manifest url.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/fragment-level--invalid-url');
+ expect(await page.locator('.fragment').textContent()).toContain('Hello World!');
+ });
+
+ test('Replaces the async fragment content with the variant.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/fragment-level--async');
+ expect(await page.locator('.fragment').textContent()).toContain('Hello v2!');
+ });
+
+ test('Sets classes on the section for the audience.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/fragment-level');
+ expect(await page.locator('.fragment').getAttribute('class')).toContain('audience-foo');
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/fragment-level?audience=bar');
+ expect(await page.locator('.fragment').getAttribute('class')).toContain('audience-bar');
+ });
+
+ test('Exposes the audiences in a JS API.', async ({ page }) => {
+ await goToAndRunAudience(page, '/tests/fixtures/audiences/fragment-level');
+ expect(await page.evaluate(() => window.hlx.audiences)).toContainEqual(
+ expect.objectContaining({
+ type: 'fragment',
+ config: expect.objectContaining({
+ configuredAudiences: {
+ foo: '/tests/fixtures/audiences/variant-1',
+ bar: '/tests/fixtures/audiences/variant-2',
+ },
+ resolvedAudiences: ['foo'],
+ selectedAudience: 'foo',
+ }),
+ servedExperience: '/tests/fixtures/audiences/variant-1',
+ }),
+ );
+ });
+
+ test('triggers a DOM event with the audience detail', async ({ page }) => {
+ const fn = await waitForDomEvent(page, 'aem:experimentation');
+ await page.goto('/tests/fixtures/audiences/fragment-level');
+ expect(await page.evaluate(fn)).toEqual({
+ type: 'audience',
+ element: await page.evaluate(() => document.querySelector('.fragment')),
+ audience: 'foo',
+ });
+ });
+});
diff --git a/plugins/experimentation/tests/campaigns.test.js b/plugins/experimentation/tests/campaigns.test.js
new file mode 100644
index 00000000..2218febf
--- /dev/null
+++ b/plugins/experimentation/tests/campaigns.test.js
@@ -0,0 +1,206 @@
+/* eslint-disable import/no-extraneous-dependencies */
+import { test, expect } from '@playwright/test';
+import { track } from './coverage.js';
+import { goToAndRunCampaign, waitForDomEvent } from './utils.js';
+
+track(test);
+
+test.describe('Page-level campaigns', () => {
+ test('Replaces the page content with the variant.', async ({ page }) => {
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/page-level');
+ expect(await page.locator('main').textContent()).toContain('Hello World!');
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/page-level?campaign=foo');
+ expect(await page.locator('main').textContent()).toContain('Hello v1!');
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/page-level?campaign=bar');
+ expect(await page.locator('main').textContent()).toContain('Hello v2!');
+ });
+
+ test('Serves the campaign if the configured audience is resolved.', async ({ page }) => {
+ await page.addInitScript(() => {
+ window.AUDIENCES = { baz: () => false };
+ });
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/page-level--audiences?campaign=foo');
+ expect(await page.locator('main').textContent()).toContain('Hello World!');
+ await page.addInitScript(() => {
+ window.AUDIENCES = { baz: () => true };
+ });
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/page-level--audiences?campaign=foo');
+ expect(await page.locator('main').textContent()).toContain('Hello v1!');
+ });
+
+ test('Sets a class on the body for the active campaign.', async ({ page }) => {
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/page-level');
+ expect(await page.locator('body').getAttribute('class')).toContain('campaign-default');
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/page-level?campaign=foo');
+ expect(await page.locator('body').getAttribute('class')).toContain('campaign-foo');
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/page-level?campaign=bar');
+ expect(await page.locator('body').getAttribute('class')).toContain('campaign-bar');
+ });
+
+ test('Ignores empty campaigns.', async ({ page }) => {
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/page-level--empty?campaign=foo');
+ expect(await page.locator('main').textContent()).toContain('Hello World!');
+ expect(await page.locator('body').getAttribute('class')).toContain('campaign-default');
+ });
+
+ test('Controls the campaign shown via UTM query parameters.', async ({ page }) => {
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/page-level?utm_campaign=foo');
+ expect(await page.locator('main').textContent()).toContain('Hello v1!');
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/page-level?utm_campaign=bar');
+ expect(await page.locator('main').textContent()).toContain('Hello v2!');
+ });
+
+ test('Ignores invalid campaigns references in the query parameters.', async ({ page }) => {
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/page-level?campaign=baz');
+ expect(await page.locator('main').textContent()).toContain('Hello World!');
+ });
+
+ test('Ignores invalid variant urls.', async ({ page }) => {
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/page-level--invalid-url?campaign=foo');
+ expect(await page.locator('main').textContent()).toContain('Hello World!');
+ });
+
+ test('Tracks the campaign in RUM.', async ({ page }) => {
+ await page.addInitScript(() => {
+ window.rumCalls = [];
+ window.hlx = { rum: { sampleRUM: (...args) => window.rumCalls.push(args) } };
+ });
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/page-level?campaign=foo');
+ expect(await page.evaluate(() => window.rumCalls)).toContainEqual([
+ 'campaign',
+ expect.objectContaining({
+ source: 'campaign-foo',
+ target: 'foo',
+ }),
+ ]);
+ });
+
+ test('Exposes the campaign in a JS API.', async ({ page }) => {
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/page-level?campaign=bar');
+ expect(await page.evaluate(() => window.hlx.campaigns)).toContainEqual(
+ expect.objectContaining({
+ type: 'page',
+ config: expect.objectContaining({
+ configuredCampaigns: {
+ foo: '/tests/fixtures/campaigns/variant-1',
+ bar: '/tests/fixtures/campaigns/variant-2',
+ },
+ selectedCampaign: 'bar',
+ }),
+ servedExperience: '/tests/fixtures/campaigns/variant-2',
+ }),
+ );
+ });
+
+ test('triggers a DOM event with the campaign detail', async ({ page }) => {
+ const fn = await waitForDomEvent(page, 'aem:experimentation');
+ await page.goto('/tests/fixtures/campaigns/page-level?campaign=bar');
+ expect(await page.evaluate(fn)).toEqual({
+ type: 'campaign',
+ element: await page.evaluate(() => document.body),
+ campaign: 'bar',
+ });
+ });
+});
+
+test.describe('Section-level campaigns', () => {
+ test('Replaces the section content with the variant.', async ({ page }) => {
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/section-level?campaign=bar');
+ expect(await page.locator('main>div').textContent()).toContain('Hello v2!');
+ });
+
+ test('Sets classes on the section for the campaign.', async ({ page }) => {
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/section-level?campaign=foo');
+ expect(await page.locator('main>div').getAttribute('class')).toContain('campaign-foo');
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/section-level?campaign=bar');
+ expect(await page.locator('main>div').getAttribute('class')).toContain('campaign-bar');
+ });
+
+ test('Exposes the campaigns in a JS API.', async ({ page }) => {
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/section-level?campaign=bar');
+ expect(await page.evaluate(() => window.hlx.campaigns)).toContainEqual(
+ expect.objectContaining({
+ type: 'section',
+ config: expect.objectContaining({
+ configuredCampaigns: {
+ foo: '/tests/fixtures/campaigns/variant-1',
+ bar: '/tests/fixtures/campaigns/variant-2',
+ },
+ selectedCampaign: 'bar',
+ }),
+ servedExperience: '/tests/fixtures/campaigns/variant-2',
+ }),
+ );
+ });
+
+ test('triggers a DOM event with the campaign detail', async ({ page }) => {
+ const fn = await waitForDomEvent(page, 'aem:experimentation');
+ await page.goto('/tests/fixtures/campaigns/section-level?campaign=bar');
+ expect(await page.evaluate(fn)).toEqual({
+ type: 'campaign',
+ element: await page.evaluate(() => document.querySelector('.section')),
+ campaign: 'bar',
+ });
+ });
+});
+
+test.describe('Fragment-level campaigns', () => {
+ test('Replaces the fragment content with the variant.', async ({ page }) => {
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/fragment-level?campaign=foo');
+ expect(await page.locator('.fragment').textContent()).toContain('Hello v1!');
+ });
+
+ test('Supports plural format for manifest keys.', async ({ page }) => {
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/fragment-level--alt?campaign=foo');
+ expect(await page.locator('.fragment').textContent()).toContain('Hello v1!');
+ });
+
+ test('Ignores invalid manifest url.', async ({ page }) => {
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/fragment-level--invalid-url?campaign=foo');
+ expect(await page.locator('.fragment').textContent()).toContain('Hello World!');
+ });
+
+ test('Sets classes on the section for the campaign.', async ({ page }) => {
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/fragment-level?campaign=foo');
+ expect(await page.locator('.fragment').getAttribute('class')).toContain('campaign-foo');
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/fragment-level?campaign=bar');
+ expect(await page.locator('.fragment').getAttribute('class')).toContain('campaign-bar');
+ });
+
+ test('Exposes the campaigns in a JS API.', async ({ page }) => {
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/fragment-level?campaign=foo');
+ expect(await page.evaluate(() => window.hlx.campaigns)).toContainEqual(
+ expect.objectContaining({
+ type: 'fragment',
+ config: expect.objectContaining({
+ configuredCampaigns: {
+ foo: '/tests/fixtures/campaigns/variant-1',
+ bar: '/tests/fixtures/campaigns/variant-2',
+ },
+ selectedCampaign: 'foo',
+ }),
+ servedExperience: '/tests/fixtures/campaigns/variant-1',
+ }),
+ );
+ });
+
+ test('triggers a DOM event with the campaign detail', async ({ page }) => {
+ const fn = await waitForDomEvent(page, 'aem:experimentation');
+ await page.goto('/tests/fixtures/campaigns/fragment-level?campaign=foo');
+ expect(await page.evaluate(fn)).toEqual({
+ type: 'campaign',
+ element: await page.evaluate(() => document.querySelector('.fragment')),
+ campaign: 'foo',
+ });
+ });
+});
+
+test.describe('Backward Compatibility with v1', () => {
+ test('Support the old "audience" metadata.', async ({ page }) => {
+ await page.addInitScript(() => {
+ window.AUDIENCES = { baz: () => true };
+ });
+ await goToAndRunCampaign(page, '/tests/fixtures/campaigns/page-level--backward-compatibility--audience?campaign=foo');
+ expect(await page.locator('main').textContent()).toContain('Hello v1!');
+ });
+});
diff --git a/plugins/experimentation/tests/coverage.js b/plugins/experimentation/tests/coverage.js
new file mode 100644
index 00000000..939df135
--- /dev/null
+++ b/plugins/experimentation/tests/coverage.js
@@ -0,0 +1,37 @@
+// eslint-disable-next-line import/no-extraneous-dependencies
+import MCR from 'monocart-coverage-reports';
+
+const coverageReport = MCR({
+ name: 'AEM Experimentation Plugin Coverage Report',
+ outputDir: './coverage',
+ reports: ['v8', 'console-details', 'codecov'],
+ entryFilter: {
+ '**/src/ued.js': false,
+ '**/src/**': true,
+ },
+});
+
+export async function start() {
+ // Nothing to do here
+}
+
+export async function end() {
+ await coverageReport.generate();
+}
+
+export function track(test) {
+ test.beforeEach(async ({ page }) => {
+ await Promise.all([
+ page.coverage.startJSCoverage({ resetOnNavigation: false }),
+ page.coverage.startCSSCoverage({ resetOnNavigation: false }),
+ ]);
+ });
+
+ test.afterEach(async ({ page }) => {
+ const [jsCoverage, cssCoverage] = await Promise.all([
+ page.coverage.stopJSCoverage(),
+ page.coverage.stopCSSCoverage(),
+ ]);
+ await coverageReport.add([...jsCoverage, ...cssCoverage]);
+ });
+}
diff --git a/plugins/experimentation/tests/experiments.test.js b/plugins/experimentation/tests/experiments.test.js
new file mode 100644
index 00000000..883ce274
--- /dev/null
+++ b/plugins/experimentation/tests/experiments.test.js
@@ -0,0 +1,321 @@
+/* eslint-disable import/no-extraneous-dependencies */
+import { test, expect } from '@playwright/test';
+import { track } from './coverage.js';
+import { goToAndRunExperiment, waitForDomEvent } from './utils.js';
+
+track(test);
+
+test.describe('Page-level experiments', () => {
+ test('Replaces the page content with the variant.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level');
+ expect(await page.locator('main').textContent()).toMatch(/Hello (World|v1|v2)!/);
+ });
+
+ test('Visiting the page multiple times yields the same variant', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level');
+ const text = await page.locator('main').textContent();
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level');
+ expect(await page.locator('main').textContent()).toEqual(text);
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level');
+ expect(await page.locator('main').textContent()).toEqual(text);
+ });
+
+ test('does not run inactive experiments.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level--inactive');
+ expect(await page.locator('main').textContent()).toEqual('Hello World!');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level--inactive?experiment=foo/challenger-1');
+ expect(await page.locator('main').textContent()).toEqual('Hello v1!');
+ });
+
+ test('Serves the variant if the configured audience is resolved.', async ({ page }) => {
+ await page.addInitScript(() => {
+ window.AUDIENCES = { bar: () => false };
+ });
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level--audiences?experiment=foo/challenger-1');
+ expect(await page.locator('main').textContent()).toEqual('Hello World!');
+ await page.addInitScript(() => {
+ window.AUDIENCES = { bar: () => true };
+ });
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level--audiences?experiment=foo/challenger-1');
+ expect(await page.locator('main').textContent()).toEqual('Hello v1!');
+ await page.addInitScript(() => {
+ window.AUDIENCES = { bar: async () => Promise.resolve(true) };
+ });
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level--audiences?experiment=foo/challenger-2');
+ expect(await page.locator('main').textContent()).toEqual('Hello v2!');
+ });
+
+ test('Supports the "stard-date" and "end-date" metadata.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level--time-bound');
+ expect(await page.locator('main').textContent()).toMatch(/Hello (World|v1|v2)!/);
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level--time-bound-start');
+ expect(await page.locator('main').textContent()).toEqual('Hello World!');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level--time-bound-end');
+ expect(await page.locator('main').textContent()).toEqual('Hello World!');
+ });
+
+ test('Supports the "split" metadata.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level--split');
+ expect(await page.locator('main').textContent()).toEqual('Hello v2!');
+ });
+
+ test('Sets classes on the body for the experiment.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level?experiment=foo/control');
+ expect(await page.locator('body').getAttribute('class')).toContain('experiment-foo');
+ expect(await page.locator('body').getAttribute('class')).toContain('variant-control');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level?experiment=foo/challenger-1');
+ expect(await page.locator('body').getAttribute('class')).toContain('experiment-foo');
+ expect(await page.locator('body').getAttribute('class')).toContain('variant-challenger-1');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level?experiment=foo/challenger-2');
+ expect(await page.locator('body').getAttribute('class')).toContain('experiment-foo');
+ expect(await page.locator('body').getAttribute('class')).toContain('variant-challenger-2');
+ });
+
+ test('Ignores empty experiments.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level--empty?experiment=foo/challenger-1');
+ expect(await page.locator('main').textContent()).toEqual('Hello World!');
+ expect(await page.locator('body').getAttribute('class')).not.toContain('experiment-foo');
+ expect(await page.locator('body').getAttribute('class')).not.toContain('variant-control');
+
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level--empty2?experiment=foo/challenger-1');
+ expect(await page.locator('main').textContent()).toEqual('Hello World!');
+ expect(await page.locator('body').getAttribute('class')).not.toContain('experiment-foo');
+ expect(await page.locator('body').getAttribute('class')).not.toContain('variant-control');
+ });
+
+ test('Ignores invalid experiment references in the query parameters.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level?experiment=foo/invalid');
+ expect(await page.locator('main').textContent()).toMatch(/Hello (World|v1|v2)!/);
+ });
+
+ test('Ignores invalid variant urls.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level--invalid-url?experiment=foo/challenger-1');
+ expect(await page.locator('main').textContent()).toEqual('Hello World!');
+ expect(await page.locator('body').getAttribute('class')).toContain('experiment-foo');
+ expect(await page.locator('body').getAttribute('class')).toContain('variant-control');
+ });
+
+ test('Supports code experiments.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level--code?experiment=foo/challenger-1');
+ expect(await page.locator('main').textContent()).toEqual('Hello World!');
+ expect(await page.locator('body').getAttribute('class')).toContain('experiment-foo');
+ expect(await page.locator('body').getAttribute('class')).toContain('variant-challenger-1');
+ });
+
+ test('Tracks the experiment in RUM.', async ({ page }) => {
+ await page.addInitScript(() => {
+ window.rumCalls = [];
+ window.hlx = { rum: { sampleRUM: (...args) => window.rumCalls.push(args) } };
+ });
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level');
+ expect(await page.evaluate(() => window.rumCalls)).toContainEqual([
+ 'experiment',
+ expect.objectContaining({
+ source: 'foo',
+ target: expect.stringMatching(/control|challenger-1|challenger-2/),
+ }),
+ ]);
+ });
+
+ test('Exposes the experiment in a JS API.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level');
+ expect(await page.evaluate(() => window.hlx.experiments)).toContainEqual(
+ expect.objectContaining({
+ type: 'page',
+ config: expect.objectContaining({
+ id: 'foo',
+ run: true,
+ selectedVariant: expect.stringMatching(/control|challenger-1|challenger-2/),
+ status: 'active',
+ variants: {
+ control: expect.objectContaining({ percentageSplit: '0.3334' }),
+ 'challenger-1': expect.objectContaining({ percentageSplit: '0.3333' }),
+ 'challenger-2': expect.objectContaining({ percentageSplit: '0.3333' }),
+ },
+ }),
+ servedExperience: expect.stringContaining('/tests/fixtures/experiments/page-level'),
+ }),
+ );
+ });
+
+ test('Controls the variant shown via query parameters.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level?experiment=foo/control');
+ expect(await page.locator('main').textContent()).toEqual('Hello World!');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level?experiment=foo/challenger-1');
+ expect(await page.locator('main').textContent()).toEqual('Hello v1!');
+ });
+
+ test('supports overriding the shown experiment and variant via query parameters.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level?experiment=foo/challenger-2&experiment=bar/challenger-1');
+ expect(await page.locator('main').textContent()).toEqual('Hello v2!');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level?experiment=foo&experiment-variant=challenger-1');
+ expect(await page.locator('main').textContent()).toEqual('Hello v1!');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level--audiences?experiment=foo&experiment-variant=challenger-2&audience=bar');
+ expect(await page.locator('main').textContent()).toEqual('Hello v2!');
+ });
+
+ test('triggers a DOM event with the experiment detail', async ({ page }) => {
+ const fn = await waitForDomEvent(page, 'aem:experimentation');
+ await page.goto('/tests/fixtures/experiments/page-level?experiment=foo&experiment-variant=challenger-1');
+ expect(await page.evaluate(fn)).toEqual({
+ type: 'experiment',
+ element: await page.evaluate(() => document.body),
+ experiment: 'foo',
+ variant: 'challenger-1',
+ });
+ });
+});
+
+test.describe('Section-level experiments', () => {
+ test('Replaces the section content with the variant.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/section-level');
+ expect(await page.locator('main>div').textContent()).toMatch(/Hello (World|v1|v2)!/);
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/section-level?experiment=bar/control');
+ expect(await page.locator('main>div').textContent()).toContain('Hello World!');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/section-level?experiment=bar/challenger-1');
+ expect(await page.locator('main>div').textContent()).toContain('Hello v1!');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/section-level?experiment=bar/challenger-2');
+ expect(await page.locator('main>div').textContent()).toContain('Hello v2!');
+ });
+
+ test('Sets classes on the section for the experiment.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/section-level?experiment=bar/control');
+ expect(await page.locator('main>div').getAttribute('class')).toContain('experiment-bar');
+ expect(await page.locator('main>div').getAttribute('class')).toContain('variant-control');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/section-level?experiment=bar/challenger-1');
+ expect(await page.locator('main>div').getAttribute('class')).toContain('experiment-bar');
+ expect(await page.locator('main>div').getAttribute('class')).toContain('variant-challenger-1');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/section-level?experiment=bar/challenger-2');
+ expect(await page.locator('main>div').getAttribute('class')).toContain('experiment-bar');
+ expect(await page.locator('main>div').getAttribute('class')).toContain('variant-challenger-2');
+ });
+
+ test('Exposes the experiment in a JS API.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/section-level');
+ expect(await page.evaluate(() => window.hlx.experiments)).toContainEqual(
+ expect.objectContaining({
+ type: 'section',
+ config: expect.objectContaining({
+ id: 'bar',
+ run: true,
+ selectedVariant: expect.stringMatching(/control|challenger-1|challenger-2/),
+ status: 'active',
+ variants: {
+ control: expect.objectContaining({ percentageSplit: '0.3334' }),
+ 'challenger-1': expect.objectContaining({ percentageSplit: '0.3333' }),
+ 'challenger-2': expect.objectContaining({ percentageSplit: '0.3333' }),
+ },
+ }),
+ servedExperience: expect.stringMatching(/\/tests\/fixtures\/experiments\/(page|section)-level/),
+ }),
+ );
+ });
+
+ test('triggers a DOM event with the experiment detail', async ({ page }) => {
+ const fn = await waitForDomEvent(page, 'aem:experimentation');
+ await page.goto('/tests/fixtures/experiments/section-level?experiment=bar/challenger-2');
+ expect(await page.evaluate(fn)).toEqual({
+ type: 'experiment',
+ element: await page.evaluate(() => document.querySelector('.section')),
+ experiment: 'bar',
+ variant: 'challenger-2',
+ });
+ });
+});
+
+test.describe('Fragment-level experiments', () => {
+ test('Replaces the fragment content with the variant.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/fragment-level');
+ expect(await page.locator('.fragment').first().textContent()).toMatch(/Hello (World|v1|v2)!/);
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/fragment-level?experiment=baz/control');
+ expect(await page.locator('.fragment').first().textContent()).toContain('Hello World!');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/fragment-level?experiment=baz/challenger-1');
+ expect(await page.locator('.fragment').first().textContent()).toContain('Hello v1!');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/fragment-level?experiment=baz/challenger-2');
+ expect(await page.locator('.fragment').first().textContent()).toContain('Hello v2!');
+ });
+
+ test('Supports plural format for manifest keys.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/fragment-level--alt?experiment=baz/control');
+ expect(await page.locator('.fragment').first().textContent()).toContain('Hello World!');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/fragment-level--alt?experiment=baz/challenger-1');
+ expect(await page.locator('.fragment').first().textContent()).toContain('Hello v1!');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/fragment-level--alt?experiment=baz/challenger-2');
+ expect(await page.locator('.fragment').first().textContent()).toContain('Hello v2!');
+ });
+
+ test('Ignores invalid manifest url.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/fragment-level--invalid-url');
+ expect(await page.locator('.fragment').first().textContent()).toContain('Hello World!');
+ });
+
+ test('Replaces the async fragment content with the variant.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/fragment-level--async');
+ expect(await page.locator('.fragment').first().textContent()).toMatch(/Hello (World|v1|v2)!/);
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/fragment-level--async?experiment=baz/control');
+ expect(await page.locator('.fragment').first().textContent()).toContain('Hello World!');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/fragment-level--async?experiment=baz/challenger-1');
+ expect(await page.locator('.fragment').first().textContent()).toContain('Hello v1!');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/fragment-level--async?experiment=baz/challenger-2');
+ expect(await page.locator('.fragment').first().textContent()).toContain('Hello v2!');
+ });
+
+ test('Sets classes on the section for the experiment.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/fragment-level?experiment=baz/control');
+ expect(await page.locator('.fragment').first().getAttribute('class')).toContain('experiment-baz');
+ expect(await page.locator('.fragment').first().getAttribute('class')).toContain('variant-control');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/fragment-level?experiment=baz/challenger-1');
+ expect(await page.locator('.fragment').first().getAttribute('class')).toContain('experiment-baz');
+ expect(await page.locator('.fragment').first().getAttribute('class')).toContain('variant-challenger-1');
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/fragment-level?experiment=baz/challenger-2');
+ expect(await page.locator('.fragment').first().getAttribute('class')).toContain('experiment-baz');
+ expect(await page.locator('.fragment').first().getAttribute('class')).toContain('variant-challenger-2');
+ });
+
+ test('Exposes the experiment in a JS API.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/fragment-level');
+ expect(await page.evaluate(() => window.hlx.experiments)).toContainEqual(
+ expect.objectContaining({
+ type: 'fragment',
+ config: expect.objectContaining({
+ id: 'baz',
+ run: true,
+ selectedVariant: expect.stringMatching(/control|challenger-1|challenger-2/),
+ status: 'active',
+ variants: {
+ control: expect.objectContaining({ percentageSplit: '0.3334' }),
+ 'challenger-1': expect.objectContaining({ percentageSplit: '0.3333' }),
+ 'challenger-2': expect.objectContaining({ percentageSplit: '0.3333' }),
+ },
+ }),
+ servedExperience: expect.stringMatching(/\/tests\/fixtures\/experiments\/(fragment|section)-level/),
+ }),
+ );
+ });
+
+ test('triggers a DOM event with the experiment detail', async ({ page }) => {
+ const fn = await waitForDomEvent(page, 'aem:experimentation');
+ await page.goto('/tests/fixtures/experiments/fragment-level?experiment=baz/challenger-1');
+ expect(await page.evaluate(fn)).toEqual({
+ type: 'experiment',
+ element: await page.evaluate(() => document.querySelector('.fragment')),
+ experiment: 'baz',
+ variant: 'challenger-1',
+ });
+ });
+});
+
+test.describe('Backward Compatibility with v1', () => {
+ test('Support the old "instant-experiment" metadata.', async ({ page }) => {
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level--backward-compatibility--instant-experiment?experiment=foo/challenger-1');
+ expect(await page.locator('main').textContent()).toEqual('Hello v1!');
+ });
+
+ test('Support the old "audience" metadata.', async ({ page }) => {
+ await page.addInitScript(() => {
+ window.AUDIENCES = { bar: () => true };
+ });
+ await goToAndRunExperiment(page, '/tests/fixtures/experiments/page-level--backward-compatibility--audience?experiment=foo/challenger-1');
+ expect(await page.locator('main').textContent()).toEqual('Hello v1!');
+ });
+});
diff --git a/plugins/experimentation/tests/fixtures/aem.js b/plugins/experimentation/tests/fixtures/aem.js
new file mode 100644
index 00000000..61527b42
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/aem.js
@@ -0,0 +1,759 @@
+/*
+ * Copyright 2024 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+
+/* eslint-env browser */
+
+/**
+ * log RUM if part of the sample.
+ * @param {string} checkpoint identifies the checkpoint in funnel
+ * @param {Object} data additional data for RUM sample
+ * @param {string} data.source DOM node that is the source of a checkpoint event,
+ * identified by #id or .classname
+ * @param {string} data.target subject of the checkpoint event,
+ * for instance the href of a link, or a search term
+ */
+function sampleRUM(checkpoint, data = {}) {
+ const SESSION_STORAGE_KEY = 'aem-rum';
+ sampleRUM.baseURL = sampleRUM.baseURL
+ || new URL(window.RUM_BASE == null ? 'https://rum.hlx.page' : window.RUM_BASE, window.location);
+ sampleRUM.defer = sampleRUM.defer || [];
+ const defer = (fnname) => {
+ sampleRUM[fnname] = sampleRUM[fnname] || ((...args) => sampleRUM.defer.push({ fnname, args }));
+ };
+ sampleRUM.drain = sampleRUM.drain
+ || ((dfnname, fn) => {
+ sampleRUM[dfnname] = fn;
+ sampleRUM.defer
+ .filter(({ fnname }) => dfnname === fnname)
+ .forEach(({ fnname, args }) => sampleRUM[fnname](...args));
+ });
+ sampleRUM.always = sampleRUM.always || [];
+ sampleRUM.always.on = (chkpnt, fn) => {
+ sampleRUM.always[chkpnt] = fn;
+ };
+ sampleRUM.on = (chkpnt, fn) => {
+ sampleRUM.cases[chkpnt] = fn;
+ };
+ defer('observe');
+ defer('cwv');
+ try {
+ window.hlx = window.hlx || {};
+ if (!window.hlx.rum) {
+ const usp = new URLSearchParams(window.location.search);
+ const weight = usp.get('rum') === 'on' ? 1 : 100; // with parameter, weight is 1. Defaults to 100.
+ const id = Array.from({ length: 75 }, (_, i) => String.fromCharCode(48 + i))
+ .filter((a) => /\d|[A-Z]/i.test(a))
+ .filter(() => Math.random() * 75 > 70)
+ .join('');
+ const random = Math.random();
+ const isSelected = random * weight < 1;
+ const firstReadTime = window.performance ? window.performance.timeOrigin : Date.now();
+ const urlSanitizers = {
+ full: () => window.location.href,
+ origin: () => window.location.origin,
+ path: () => window.location.href.replace(/\?.*$/, ''),
+ };
+ // eslint-disable-next-line max-len
+ const rumSessionStorage = sessionStorage.getItem(SESSION_STORAGE_KEY)
+ ? JSON.parse(sessionStorage.getItem(SESSION_STORAGE_KEY))
+ : {};
+ // eslint-disable-next-line max-len
+ rumSessionStorage.pages = (rumSessionStorage.pages ? rumSessionStorage.pages : 0)
+ + 1
+ /* noise */ + (Math.floor(Math.random() * 20) - 10);
+ sessionStorage.setItem(SESSION_STORAGE_KEY, JSON.stringify(rumSessionStorage));
+ // eslint-disable-next-line object-curly-newline, max-len
+ window.hlx.rum = {
+ weight,
+ id,
+ random,
+ isSelected,
+ firstReadTime,
+ sampleRUM,
+ sanitizeURL: urlSanitizers[window.hlx.RUM_MASK_URL || 'path'],
+ rumSessionStorage,
+ };
+ }
+
+ const { weight, id, firstReadTime } = window.hlx.rum;
+ if (window.hlx && window.hlx.rum && window.hlx.rum.isSelected) {
+ const knownProperties = [
+ 'weight',
+ 'id',
+ 'referer',
+ 'checkpoint',
+ 't',
+ 'source',
+ 'target',
+ 'cwv',
+ 'CLS',
+ 'FID',
+ 'LCP',
+ 'INP',
+ 'TTFB',
+ ];
+ const sendPing = (pdata = data) => {
+ // eslint-disable-next-line max-len
+ const t = Math.round(
+ window.performance ? window.performance.now() : Date.now() - firstReadTime,
+ );
+ // eslint-disable-next-line object-curly-newline, max-len, no-use-before-define
+ const body = JSON.stringify(
+ {
+ weight, id, referer: window.hlx.rum.sanitizeURL(), checkpoint, t, ...data,
+ },
+ knownProperties,
+ );
+ const url = new URL(`.rum/${weight}`, sampleRUM.baseURL).href;
+ navigator.sendBeacon(url, body);
+ // eslint-disable-next-line no-console
+ console.debug(`ping:${checkpoint}`, pdata);
+ };
+ sampleRUM.cases = sampleRUM.cases || {
+ load: () => sampleRUM('pagesviewed', { source: window.hlx.rum.rumSessionStorage.pages }) || true,
+ cwv: () => sampleRUM.cwv(data) || true,
+ lazy: () => {
+ // use classic script to avoid CORS issues
+ const script = document.createElement('script');
+ script.src = new URL(
+ '.rum/@adobe/helix-rum-enhancer@^1/src/index.js',
+ sampleRUM.baseURL,
+ ).href;
+ document.head.appendChild(script);
+ return true;
+ },
+ };
+ sendPing(data);
+ if (sampleRUM.cases[checkpoint]) {
+ sampleRUM.cases[checkpoint]();
+ }
+ }
+ if (sampleRUM.always[checkpoint]) {
+ sampleRUM.always[checkpoint](data);
+ }
+ } catch (error) {
+ // something went wrong
+ }
+}
+
+/**
+ * Setup block utils.
+ */
+function setup() {
+ window.hlx = window.hlx || {};
+ window.hlx.RUM_MASK_URL = 'full';
+ window.hlx.codeBasePath = '';
+ window.hlx.lighthouse = new URLSearchParams(window.location.search).get('lighthouse') === 'on';
+
+ const scriptEl = document.querySelector('script[src$="/scripts/scripts.js"]');
+ if (scriptEl) {
+ try {
+ [window.hlx.codeBasePath] = new URL(scriptEl.src).pathname.split('/scripts/scripts.js');
+ } catch (error) {
+ // eslint-disable-next-line no-console
+ console.log(error);
+ }
+ }
+}
+
+/**
+ * Auto initializiation.
+ */
+
+function init() {
+ setup();
+}
+
+/**
+ * Sanitizes a string for use as class name.
+ * @param {string} name The unsanitized string
+ * @returns {string} The class name
+ */
+function toClassName(name) {
+ return typeof name === 'string'
+ ? name
+ .toLowerCase()
+ .replace(/[^0-9a-z]/gi, '-')
+ .replace(/-+/g, '-')
+ .replace(/^-|-$/g, '')
+ : '';
+}
+
+/**
+ * Sanitizes a string for use as a js property name.
+ * @param {string} name The unsanitized string
+ * @returns {string} The camelCased name
+ */
+function toCamelCase(name) {
+ return toClassName(name).replace(/-([a-z])/g, (g) => g[1].toUpperCase());
+}
+
+/**
+ * Extracts the config from a block.
+ * @param {Element} block The block element
+ * @returns {object} The block config
+ */
+// eslint-disable-next-line import/prefer-default-export
+function readBlockConfig(block) {
+ const config = {};
+ block.querySelectorAll(':scope > div').forEach((row) => {
+ if (row.children) {
+ const cols = [...row.children];
+ if (cols[1]) {
+ const col = cols[1];
+ const name = toClassName(cols[0].textContent);
+ let value = '';
+ if (col.querySelector('a')) {
+ const as = [...col.querySelectorAll('a')];
+ if (as.length === 1) {
+ value = as[0].href;
+ } else {
+ value = as.map((a) => a.href);
+ }
+ } else if (col.querySelector('img')) {
+ const imgs = [...col.querySelectorAll('img')];
+ if (imgs.length === 1) {
+ value = imgs[0].src;
+ } else {
+ value = imgs.map((img) => img.src);
+ }
+ } else if (col.querySelector('p')) {
+ const ps = [...col.querySelectorAll('p')];
+ if (ps.length === 1) {
+ value = ps[0].textContent;
+ } else {
+ value = ps.map((p) => p.textContent);
+ }
+ } else value = row.children[1].textContent;
+ config[name] = value;
+ }
+ }
+ });
+ return config;
+}
+
+/**
+ * Loads a CSS file.
+ * @param {string} href URL to the CSS file
+ */
+async function loadCSS(href) {
+ return new Promise((resolve, reject) => {
+ if (!document.querySelector(`head > link[href="${href}"]`)) {
+ const link = document.createElement('link');
+ link.rel = 'stylesheet';
+ link.href = href;
+ link.onload = resolve;
+ link.onerror = reject;
+ document.head.append(link);
+ } else {
+ resolve();
+ }
+ });
+}
+
+/**
+ * Loads a non module JS file.
+ * @param {string} src URL to the JS file
+ * @param {Object} attrs additional optional attributes
+ */
+async function loadScript(src, attrs) {
+ return new Promise((resolve, reject) => {
+ if (!document.querySelector(`head > script[src="${src}"]`)) {
+ const script = document.createElement('script');
+ script.src = src;
+ if (attrs) {
+ // eslint-disable-next-line no-restricted-syntax, guard-for-in
+ for (const attr in attrs) {
+ script.setAttribute(attr, attrs[attr]);
+ }
+ }
+ script.onload = resolve;
+ script.onerror = reject;
+ document.head.append(script);
+ } else {
+ resolve();
+ }
+ });
+}
+
+/**
+ * Retrieves the content of metadata tags.
+ * @param {string} name The metadata name (or property)
+ * @param {Document} doc Document object to query for metadata. Defaults to the window's document
+ * @returns {string} The metadata value(s)
+ */
+function getMetadata(name, doc = document) {
+ const attr = name && name.includes(':') ? 'property' : 'name';
+ const meta = [...doc.head.querySelectorAll(`meta[${attr}="${name}"]`)]
+ .map((m) => m.content)
+ .join(', ');
+ return meta || '';
+}
+
+/**
+ * Returns a picture element with webp and fallbacks
+ * @param {string} src The image URL
+ * @param {string} [alt] The image alternative text
+ * @param {boolean} [eager] Set loading attribute to eager
+ * @param {Array} [breakpoints] Breakpoints and corresponding params (eg. width)
+ * @returns {Element} The picture element
+ */
+function createOptimizedPicture(
+ src,
+ alt = '',
+ eager = false,
+ breakpoints = [{ media: '(min-width: 600px)', width: '2000' }, { width: '750' }],
+) {
+ const url = new URL(src, window.location.href);
+ const picture = document.createElement('picture');
+ const { pathname } = url;
+ const ext = pathname.substring(pathname.lastIndexOf('.') + 1);
+
+ // webp
+ breakpoints.forEach((br) => {
+ const source = document.createElement('source');
+ if (br.media) source.setAttribute('media', br.media);
+ source.setAttribute('type', 'image/webp');
+ source.setAttribute('srcset', `${pathname}?width=${br.width}&format=webply&optimize=medium`);
+ picture.appendChild(source);
+ });
+
+ // fallback
+ breakpoints.forEach((br, i) => {
+ if (i < breakpoints.length - 1) {
+ const source = document.createElement('source');
+ if (br.media) source.setAttribute('media', br.media);
+ source.setAttribute('srcset', `${pathname}?width=${br.width}&format=${ext}&optimize=medium`);
+ picture.appendChild(source);
+ } else {
+ const img = document.createElement('img');
+ img.setAttribute('loading', eager ? 'eager' : 'lazy');
+ img.setAttribute('alt', alt);
+ picture.appendChild(img);
+ img.setAttribute('src', `${pathname}?width=${br.width}&format=${ext}&optimize=medium`);
+ }
+ });
+
+ return picture;
+}
+
+/**
+ * Set template (page structure) and theme (page styles).
+ */
+function decorateTemplateAndTheme() {
+ const addClasses = (element, classes) => {
+ classes.split(',').forEach((c) => {
+ element.classList.add(toClassName(c.trim()));
+ });
+ };
+ const template = getMetadata('template');
+ if (template) addClasses(document.body, template);
+ const theme = getMetadata('theme');
+ if (theme) addClasses(document.body, theme);
+}
+
+/**
+ * Wrap inline text content of block cells within a tag.
+ * @param {Element} block the block element
+ */
+function wrapTextNodes(block) {
+ const validWrappers = [
+ 'P',
+ 'PRE',
+ 'UL',
+ 'OL',
+ 'PICTURE',
+ 'TABLE',
+ 'H1',
+ 'H2',
+ 'H3',
+ 'H4',
+ 'H5',
+ 'H6',
+ ];
+
+ const wrap = (el) => {
+ const wrapper = document.createElement('p');
+ wrapper.append(...el.childNodes);
+ el.append(wrapper);
+ };
+
+ block.querySelectorAll(':scope > div > div').forEach((blockColumn) => {
+ if (blockColumn.hasChildNodes()) {
+ const hasWrapper = !!blockColumn.firstElementChild
+ && validWrappers.some((tagName) => blockColumn.firstElementChild.tagName === tagName);
+ if (!hasWrapper) {
+ wrap(blockColumn);
+ } else if (
+ blockColumn.firstElementChild.tagName === 'PICTURE'
+ && (blockColumn.children.length > 1 || !!blockColumn.textContent.trim())
+ ) {
+ wrap(blockColumn);
+ }
+ }
+ });
+}
+
+/**
+ * Decorates paragraphs containing a single link as buttons.
+ * @param {Element} element container element
+ */
+function decorateButtons(element) {
+ element.querySelectorAll('a').forEach((a) => {
+ a.title = a.title || a.textContent;
+ if (a.href !== a.textContent) {
+ const up = a.parentElement;
+ const twoup = a.parentElement.parentElement;
+ if (!a.querySelector('img')) {
+ if (up.childNodes.length === 1 && (up.tagName === 'P' || up.tagName === 'DIV')) {
+ a.className = 'button'; // default
+ up.classList.add('button-container');
+ }
+ if (
+ up.childNodes.length === 1
+ && up.tagName === 'STRONG'
+ && twoup.childNodes.length === 1
+ && twoup.tagName === 'P'
+ ) {
+ a.className = 'button primary';
+ twoup.classList.add('button-container');
+ }
+ if (
+ up.childNodes.length === 1
+ && up.tagName === 'EM'
+ && twoup.childNodes.length === 1
+ && twoup.tagName === 'P'
+ ) {
+ a.className = 'button secondary';
+ twoup.classList.add('button-container');
+ }
+ }
+ }
+ });
+}
+
+/**
+ * Add for icon, prefixed with codeBasePath and optional prefix.
+ * @param {Element} [span] span element with icon classes
+ * @param {string} [prefix] prefix to be added to icon src
+ * @param {string} [alt] alt text to be added to icon
+ */
+function decorateIcon(span, prefix = '', alt = '') {
+ const iconName = Array.from(span.classList)
+ .find((c) => c.startsWith('icon-'))
+ .substring(5);
+ const img = document.createElement('img');
+ img.dataset.iconName = iconName;
+ img.src = `${window.hlx.codeBasePath}${prefix}/icons/${iconName}.svg`;
+ img.alt = alt;
+ img.loading = 'lazy';
+ span.append(img);
+}
+
+/**
+ * Add for icons, prefixed with codeBasePath and optional prefix.
+ * @param {Element} [element] Element containing icons
+ * @param {string} [prefix] prefix to be added to icon the src
+ */
+function decorateIcons(element, prefix = '') {
+ const icons = [...element.querySelectorAll('span.icon')];
+ icons.forEach((span) => {
+ decorateIcon(span, prefix);
+ });
+}
+
+/**
+ * Decorates all sections in a container element.
+ * @param {Element} main The container element
+ */
+function decorateSections(main) {
+ main.querySelectorAll(':scope > div').forEach((section) => {
+ const wrappers = [];
+ let defaultContent = false;
+ [...section.children].forEach((e) => {
+ if (e.tagName === 'DIV' || !defaultContent) {
+ const wrapper = document.createElement('div');
+ wrappers.push(wrapper);
+ defaultContent = e.tagName !== 'DIV';
+ if (defaultContent) wrapper.classList.add('default-content-wrapper');
+ }
+ wrappers[wrappers.length - 1].append(e);
+ });
+ wrappers.forEach((wrapper) => section.append(wrapper));
+ section.classList.add('section');
+ section.dataset.sectionStatus = 'initialized';
+ section.style.display = 'none';
+
+ // Process section metadata
+ const sectionMeta = section.querySelector('div.section-metadata');
+ if (sectionMeta) {
+ const meta = readBlockConfig(sectionMeta);
+ Object.keys(meta).forEach((key) => {
+ if (key === 'style') {
+ const styles = meta.style
+ .split(',')
+ .filter((style) => style)
+ .map((style) => toClassName(style.trim()));
+ styles.forEach((style) => section.classList.add(style));
+ } else {
+ section.dataset[toCamelCase(key)] = meta[key];
+ }
+ });
+ sectionMeta.parentNode.remove();
+ }
+ });
+}
+
+/**
+ * Gets placeholders object.
+ * @param {string} [prefix] Location of placeholders
+ * @returns {object} Window placeholders object
+ */
+// eslint-disable-next-line import/prefer-default-export
+async function fetchPlaceholders(prefix = 'default') {
+ window.placeholders = window.placeholders || {};
+ if (!window.placeholders[prefix]) {
+ window.placeholders[prefix] = new Promise((resolve) => {
+ fetch(`${prefix === 'default' ? '' : prefix}/placeholders.json`)
+ .then((resp) => {
+ if (resp.ok) {
+ return resp.json();
+ }
+ return {};
+ })
+ .then((json) => {
+ const placeholders = {};
+ json.data
+ .filter((placeholder) => placeholder.Key)
+ .forEach((placeholder) => {
+ placeholders[toCamelCase(placeholder.Key)] = placeholder.Text;
+ });
+ window.placeholders[prefix] = placeholders;
+ resolve(window.placeholders[prefix]);
+ })
+ .catch(() => {
+ // error loading placeholders
+ window.placeholders[prefix] = {};
+ resolve(window.placeholders[prefix]);
+ });
+ });
+ }
+ return window.placeholders[`${prefix}`];
+}
+
+/**
+ * Updates all section status in a container element.
+ * @param {Element} main The container element
+ */
+function updateSectionsStatus(main) {
+ const sections = [...main.querySelectorAll(':scope > div.section')];
+ for (let i = 0; i < sections.length; i += 1) {
+ const section = sections[i];
+ const status = section.dataset.sectionStatus;
+ if (status !== 'loaded') {
+ const loadingBlock = section.querySelector(
+ '.block[data-block-status="initialized"], .block[data-block-status="loading"]',
+ );
+ if (loadingBlock) {
+ section.dataset.sectionStatus = 'loading';
+ break;
+ } else {
+ section.dataset.sectionStatus = 'loaded';
+ section.style.display = null;
+ }
+ }
+ }
+}
+
+/**
+ * Builds a block DOM Element from a two dimensional array, string, or object
+ * @param {string} blockName name of the block
+ * @param {*} content two dimensional array or string or object of content
+ */
+function buildBlock(blockName, content) {
+ const table = Array.isArray(content) ? content : [[content]];
+ const blockEl = document.createElement('div');
+ // build image block nested div structure
+ blockEl.classList.add(blockName);
+ table.forEach((row) => {
+ const rowEl = document.createElement('div');
+ row.forEach((col) => {
+ const colEl = document.createElement('div');
+ const vals = col.elems ? col.elems : [col];
+ vals.forEach((val) => {
+ if (val) {
+ if (typeof val === 'string') {
+ colEl.innerHTML += val;
+ } else {
+ colEl.appendChild(val);
+ }
+ }
+ });
+ rowEl.appendChild(colEl);
+ });
+ blockEl.appendChild(rowEl);
+ });
+ return blockEl;
+}
+
+/**
+ * Loads JS and CSS for a block.
+ * @param {Element} block The block element
+ */
+async function loadBlock(block) {
+ const status = block.dataset.blockStatus;
+ if (status !== 'loading' && status !== 'loaded') {
+ block.dataset.blockStatus = 'loading';
+ const { blockName } = block.dataset;
+ try {
+ const cssLoaded = loadCSS(`${window.hlx.codeBasePath}/blocks/${blockName}/${blockName}.css`);
+ const decorationComplete = new Promise((resolve) => {
+ (async () => {
+ try {
+ const mod = await import(
+ `${window.hlx.codeBasePath}/blocks/${blockName}/${blockName}.js`
+ );
+ if (mod.default) {
+ await mod.default(block);
+ }
+ } catch (error) {
+ // eslint-disable-next-line no-console
+ console.log(`failed to load module for ${blockName}`, error);
+ }
+ resolve();
+ })();
+ });
+ await Promise.all([cssLoaded, decorationComplete]);
+ } catch (error) {
+ // eslint-disable-next-line no-console
+ console.log(`failed to load block ${blockName}`, error);
+ }
+ block.dataset.blockStatus = 'loaded';
+ }
+ return block;
+}
+
+/**
+ * Loads JS and CSS for all blocks in a container element.
+ * @param {Element} main The container element
+ */
+async function loadBlocks(main) {
+ updateSectionsStatus(main);
+ const blocks = [...main.querySelectorAll('div.block')];
+ for (let i = 0; i < blocks.length; i += 1) {
+ // eslint-disable-next-line no-await-in-loop
+ await loadBlock(blocks[i]);
+ updateSectionsStatus(main);
+ }
+}
+
+/**
+ * Decorates a block.
+ * @param {Element} block The block element
+ */
+function decorateBlock(block) {
+ const shortBlockName = block.classList[0];
+ if (shortBlockName) {
+ block.classList.add('block');
+ block.dataset.blockName = shortBlockName;
+ block.dataset.blockStatus = 'initialized';
+ wrapTextNodes(block);
+ const blockWrapper = block.parentElement;
+ blockWrapper.classList.add(`${shortBlockName}-wrapper`);
+ const section = block.closest('.section');
+ if (section) section.classList.add(`${shortBlockName}-container`);
+ }
+}
+
+/**
+ * Decorates all blocks in a container element.
+ * @param {Element} main The container element
+ */
+function decorateBlocks(main) {
+ main.querySelectorAll('div.section > div > div').forEach(decorateBlock);
+}
+
+/**
+ * Loads a block named 'header' into header
+ * @param {Element} header header element
+ * @returns {Promise}
+ */
+async function loadHeader(header) {
+ const headerBlock = buildBlock('header', '');
+ header.append(headerBlock);
+ decorateBlock(headerBlock);
+ return loadBlock(headerBlock);
+}
+
+/**
+ * Loads a block named 'footer' into footer
+ * @param footer footer element
+ * @returns {Promise}
+ */
+async function loadFooter(footer) {
+ const footerBlock = buildBlock('footer', '');
+ footer.append(footerBlock);
+ decorateBlock(footerBlock);
+ return loadBlock(footerBlock);
+}
+
+/**
+ * Load LCP block and/or wait for LCP in default content.
+ * @param {Array} lcpBlocks Array of blocks
+ */
+async function waitForLCP(lcpBlocks) {
+ const block = document.querySelector('.block');
+ const hasLCPBlock = block && lcpBlocks.includes(block.dataset.blockName);
+ if (hasLCPBlock) await loadBlock(block);
+
+ document.body.style.display = null;
+ const lcpCandidate = document.querySelector('main img');
+
+ await new Promise((resolve) => {
+ if (lcpCandidate && !lcpCandidate.complete) {
+ lcpCandidate.setAttribute('loading', 'eager');
+ lcpCandidate.addEventListener('load', resolve);
+ lcpCandidate.addEventListener('error', resolve);
+ } else {
+ resolve();
+ }
+ });
+}
+
+init();
+
+export {
+ buildBlock,
+ createOptimizedPicture,
+ decorateBlock,
+ decorateBlocks,
+ decorateButtons,
+ decorateIcons,
+ decorateSections,
+ decorateTemplateAndTheme,
+ fetchPlaceholders,
+ getMetadata,
+ loadBlock,
+ loadBlocks,
+ loadCSS,
+ loadFooter,
+ loadHeader,
+ loadScript,
+ readBlockConfig,
+ sampleRUM,
+ setup,
+ toCamelCase,
+ toClassName,
+ updateSectionsStatus,
+ waitForLCP,
+ wrapTextNodes,
+};
diff --git a/plugins/experimentation/tests/fixtures/audiences/fragment-level--alt.html b/plugins/experimentation/tests/fixtures/audiences/fragment-level--alt.html
new file mode 100644
index 00000000..0dffb768
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/audiences/fragment-level--alt.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/audiences/fragment-level--async.html b/plugins/experimentation/tests/fixtures/audiences/fragment-level--async.html
new file mode 100644
index 00000000..64b9e1dd
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/audiences/fragment-level--async.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/audiences/fragment-level--invalid-url.html b/plugins/experimentation/tests/fixtures/audiences/fragment-level--invalid-url.html
new file mode 100644
index 00000000..19cd8305
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/audiences/fragment-level--invalid-url.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/audiences/fragment-level.html b/plugins/experimentation/tests/fixtures/audiences/fragment-level.html
new file mode 100644
index 00000000..af5b73b2
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/audiences/fragment-level.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/audiences/fragments--alt.json b/plugins/experimentation/tests/fixtures/audiences/fragments--alt.json
new file mode 100644
index 00000000..322072e5
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/audiences/fragments--alt.json
@@ -0,0 +1,17 @@
+{
+ "data": [
+ {
+ "Pages": "/tests/fixtures/audiences/fragment-level--alt",
+ "Audiences": "Foo",
+ "Selectors": ".fragment",
+ "Urls": "/tests/fixtures/audiences/variant-1"
+ },
+ {
+ "Pages": "/tests/fixtures/audiences/fragment-level--alt",
+ "Audiences": "Bar",
+ "Selectors": ".fragment",
+ "Urls": "/tests/fixtures/audiences/variant-2"
+ }
+ ],
+ ":type": "sheet"
+}
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/audiences/fragments.json b/plugins/experimentation/tests/fixtures/audiences/fragments.json
new file mode 100644
index 00000000..104f1575
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/audiences/fragments.json
@@ -0,0 +1,29 @@
+{
+ "data": [
+ {
+ "Page": "/tests/fixtures/audiences/fragment-level",
+ "Audience": "Foo",
+ "Selector": ".fragment",
+ "Url": "/tests/fixtures/audiences/variant-1"
+ },
+ {
+ "Page": "/tests/fixtures/audiences/fragment-level",
+ "Audience": "Bar",
+ "Selector": ".fragment",
+ "Url": "/tests/fixtures/audiences/variant-2"
+ },
+ {
+ "Page": "/tests/fixtures/audiences/fragment-level--async",
+ "Audience": "Foo",
+ "Selector": ".fragment",
+ "Url": "/tests/fixtures/audiences/variant-1"
+ },
+ {
+ "Page": "/tests/fixtures/audiences/fragment-level--async",
+ "Audience": "Bar",
+ "Selector": ".fragment",
+ "Url": "/tests/fixtures/audiences/variant-2"
+ }
+ ],
+ ":type": "sheet"
+}
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/audiences/page-level--async.html b/plugins/experimentation/tests/fixtures/audiences/page-level--async.html
new file mode 100644
index 00000000..267d52b6
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/audiences/page-level--async.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+ Hello World!
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/audiences/page-level--empty.html b/plugins/experimentation/tests/fixtures/audiences/page-level--empty.html
new file mode 100644
index 00000000..1f050dd5
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/audiences/page-level--empty.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+ Hello World!
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/audiences/page-level--invalid-url.html b/plugins/experimentation/tests/fixtures/audiences/page-level--invalid-url.html
new file mode 100644
index 00000000..6fec3c0c
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/audiences/page-level--invalid-url.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+ Hello World!
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/audiences/page-level--invalid.html b/plugins/experimentation/tests/fixtures/audiences/page-level--invalid.html
new file mode 100644
index 00000000..2ebf689a
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/audiences/page-level--invalid.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+ Hello World!
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/audiences/page-level.html b/plugins/experimentation/tests/fixtures/audiences/page-level.html
new file mode 100644
index 00000000..c4227ed4
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/audiences/page-level.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+ Hello World!
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/audiences/section-level.html b/plugins/experimentation/tests/fixtures/audiences/section-level.html
new file mode 100644
index 00000000..e064b2c7
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/audiences/section-level.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/audiences/variant-1.html b/plugins/experimentation/tests/fixtures/audiences/variant-1.html
new file mode 100644
index 00000000..17dc08dc
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/audiences/variant-1.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+ Hello v1!
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/audiences/variant-2.html b/plugins/experimentation/tests/fixtures/audiences/variant-2.html
new file mode 100644
index 00000000..d057125e
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/audiences/variant-2.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+ Hello v2!
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/campaigns/fragment-level--alt.html b/plugins/experimentation/tests/fixtures/campaigns/fragment-level--alt.html
new file mode 100644
index 00000000..98e88fa7
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/campaigns/fragment-level--alt.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/campaigns/fragment-level--async.html b/plugins/experimentation/tests/fixtures/campaigns/fragment-level--async.html
new file mode 100644
index 00000000..cbb28471
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/campaigns/fragment-level--async.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/campaigns/fragment-level--invalid-url.html b/plugins/experimentation/tests/fixtures/campaigns/fragment-level--invalid-url.html
new file mode 100644
index 00000000..32a782ee
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/campaigns/fragment-level--invalid-url.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/campaigns/fragment-level.html b/plugins/experimentation/tests/fixtures/campaigns/fragment-level.html
new file mode 100644
index 00000000..5cbd580c
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/campaigns/fragment-level.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/campaigns/fragments--alt.json b/plugins/experimentation/tests/fixtures/campaigns/fragments--alt.json
new file mode 100644
index 00000000..b684ee64
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/campaigns/fragments--alt.json
@@ -0,0 +1,17 @@
+{
+ "data": [
+ {
+ "Pages": "/tests/fixtures/campaigns/fragment-level--alt",
+ "Campaigns": "Foo",
+ "Selectors": ".fragment",
+ "Urls": "/tests/fixtures/campaigns/variant-1"
+ },
+ {
+ "Pages": "/tests/fixtures/campaigns/fragment-level--alt",
+ "Campaigns": "Bar",
+ "Selectors": ".fragment",
+ "Urls": "/tests/fixtures/campaigns/variant-2"
+ }
+ ],
+ ":type": "sheet"
+}
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/campaigns/fragments.json b/plugins/experimentation/tests/fixtures/campaigns/fragments.json
new file mode 100644
index 00000000..c3de752d
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/campaigns/fragments.json
@@ -0,0 +1,17 @@
+{
+ "data": [
+ {
+ "Page": "/tests/fixtures/campaigns/fragment-level",
+ "Campaign": "Foo",
+ "Selector": ".fragment",
+ "Url": "/tests/fixtures/campaigns/variant-1"
+ },
+ {
+ "Page": "/tests/fixtures/campaigns/fragment-level",
+ "Campaign": "Bar",
+ "Selector": ".fragment",
+ "Url": "/tests/fixtures/campaigns/variant-2"
+ }
+ ],
+ ":type": "sheet"
+}
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/campaigns/page-level--audiences.html b/plugins/experimentation/tests/fixtures/campaigns/page-level--audiences.html
new file mode 100644
index 00000000..5475ed8b
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/campaigns/page-level--audiences.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+ Hello World!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/campaigns/page-level--backward-compatibility--audience.html b/plugins/experimentation/tests/fixtures/campaigns/page-level--backward-compatibility--audience.html
new file mode 100644
index 00000000..e3ed2386
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/campaigns/page-level--backward-compatibility--audience.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+ Hello World!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/campaigns/page-level--empty.html b/plugins/experimentation/tests/fixtures/campaigns/page-level--empty.html
new file mode 100644
index 00000000..e6aac97e
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/campaigns/page-level--empty.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+ Hello World!
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/campaigns/page-level--invalid-url.html b/plugins/experimentation/tests/fixtures/campaigns/page-level--invalid-url.html
new file mode 100644
index 00000000..101a8b9c
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/campaigns/page-level--invalid-url.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+ Hello World!
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/campaigns/page-level.html b/plugins/experimentation/tests/fixtures/campaigns/page-level.html
new file mode 100644
index 00000000..df3ea0d9
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/campaigns/page-level.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+ Hello World!
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/campaigns/section-level.html b/plugins/experimentation/tests/fixtures/campaigns/section-level.html
new file mode 100644
index 00000000..e0b99176
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/campaigns/section-level.html
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/campaigns/variant-1.html b/plugins/experimentation/tests/fixtures/campaigns/variant-1.html
new file mode 100644
index 00000000..17dc08dc
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/campaigns/variant-1.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+ Hello v1!
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/campaigns/variant-2.html b/plugins/experimentation/tests/fixtures/campaigns/variant-2.html
new file mode 100644
index 00000000..d057125e
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/campaigns/variant-2.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+ Hello v2!
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/fragment-level--alt.html b/plugins/experimentation/tests/fixtures/experiments/fragment-level--alt.html
new file mode 100644
index 00000000..8d3307ad
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/fragment-level--alt.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/fragment-level--async.html b/plugins/experimentation/tests/fixtures/experiments/fragment-level--async.html
new file mode 100644
index 00000000..bab83092
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/fragment-level--async.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/fragment-level--invalid-url.html b/plugins/experimentation/tests/fixtures/experiments/fragment-level--invalid-url.html
new file mode 100644
index 00000000..fc9a675b
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/fragment-level--invalid-url.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/fragment-level.html b/plugins/experimentation/tests/fixtures/experiments/fragment-level.html
new file mode 100644
index 00000000..75f2a820
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/fragment-level.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/fragments--alt.json b/plugins/experimentation/tests/fixtures/experiments/fragments--alt.json
new file mode 100644
index 00000000..749999aa
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/fragments--alt.json
@@ -0,0 +1,19 @@
+{
+ "data": [
+ {
+ "Pages": "/tests/fixtures/experiments/fragment-level--alt",
+ "Experiments": "Baz",
+ "Variants": "challenger-1",
+ "Selectors": ".fragment",
+ "Urls": "/tests/fixtures/experiments/section-level-v1"
+ },
+ {
+ "Pages": "/tests/fixtures/experiments/fragment-level--alt",
+ "Experiments": "Baz",
+ "Variants": "challenger-2",
+ "Selectors": ".fragment",
+ "Urls": "/tests/fixtures/experiments/section-level-v2"
+ }
+ ],
+ ":type": "sheet"
+}
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/fragments.json b/plugins/experimentation/tests/fixtures/experiments/fragments.json
new file mode 100644
index 00000000..7fb3c722
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/fragments.json
@@ -0,0 +1,33 @@
+{
+ "data": [
+ {
+ "Page": "/tests/fixtures/experiments/fragment-level",
+ "Experiment": "Baz",
+ "Variant": "challenger-1",
+ "Selector": ".fragment",
+ "Url": "/tests/fixtures/experiments/section-level-v1"
+ },
+ {
+ "Page": "/tests/fixtures/experiments/fragment-level",
+ "Experiment": "Baz",
+ "Variant": "challenger-2",
+ "Selector": ".fragment",
+ "Url": "/tests/fixtures/experiments/section-level-v2"
+ },
+ {
+ "Page": "/tests/fixtures/experiments/fragment-level--async",
+ "Experiment": "Baz",
+ "Variant": "challenger-1",
+ "Selector": ".fragment",
+ "Url": "/tests/fixtures/experiments/section-level-v1"
+ },
+ {
+ "Page": "/tests/fixtures/experiments/fragment-level--async",
+ "Experiment": "Baz",
+ "Variant": "challenger-2",
+ "Selector": ".fragment",
+ "Url": "/tests/fixtures/experiments/section-level-v2"
+ }
+ ],
+ ":type": "sheet"
+}
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/page-level--audiences.html b/plugins/experimentation/tests/fixtures/experiments/page-level--audiences.html
new file mode 100644
index 00000000..1fab348e
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/page-level--audiences.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+ Hello World!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/page-level--backward-compatibility--audience.html b/plugins/experimentation/tests/fixtures/experiments/page-level--backward-compatibility--audience.html
new file mode 100644
index 00000000..99f19ad0
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/page-level--backward-compatibility--audience.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+ Hello World!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/page-level--backward-compatibility--instant-experiment.html b/plugins/experimentation/tests/fixtures/experiments/page-level--backward-compatibility--instant-experiment.html
new file mode 100644
index 00000000..50301eee
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/page-level--backward-compatibility--instant-experiment.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+ Hello World!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/page-level--code.html b/plugins/experimentation/tests/fixtures/experiments/page-level--code.html
new file mode 100644
index 00000000..de01d6e9
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/page-level--code.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+ Hello World!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/page-level--empty.html b/plugins/experimentation/tests/fixtures/experiments/page-level--empty.html
new file mode 100644
index 00000000..f37b132c
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/page-level--empty.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+ Hello World!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/page-level--empty2.html b/plugins/experimentation/tests/fixtures/experiments/page-level--empty2.html
new file mode 100644
index 00000000..c8f6e1fa
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/page-level--empty2.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+ Hello World!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/page-level--inactive.html b/plugins/experimentation/tests/fixtures/experiments/page-level--inactive.html
new file mode 100644
index 00000000..782081be
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/page-level--inactive.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+ Hello World!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/page-level--invalid-url.html b/plugins/experimentation/tests/fixtures/experiments/page-level--invalid-url.html
new file mode 100644
index 00000000..87cb1d45
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/page-level--invalid-url.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+ Hello World!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/page-level--split.html b/plugins/experimentation/tests/fixtures/experiments/page-level--split.html
new file mode 100644
index 00000000..17fb7462
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/page-level--split.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+ Hello World!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/page-level--time-bound-end.html b/plugins/experimentation/tests/fixtures/experiments/page-level--time-bound-end.html
new file mode 100644
index 00000000..dc3407b8
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/page-level--time-bound-end.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+ Hello World!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/page-level--time-bound-start.html b/plugins/experimentation/tests/fixtures/experiments/page-level--time-bound-start.html
new file mode 100644
index 00000000..72e12c4e
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/page-level--time-bound-start.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+ Hello World!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/page-level--time-bound.html b/plugins/experimentation/tests/fixtures/experiments/page-level--time-bound.html
new file mode 100644
index 00000000..fde3028b
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/page-level--time-bound.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+ Hello World!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/page-level-v1.html b/plugins/experimentation/tests/fixtures/experiments/page-level-v1.html
new file mode 100644
index 00000000..4771e208
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/page-level-v1.html
@@ -0,0 +1,7 @@
+
+
+
+
+ Hello v1!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/page-level-v2.html b/plugins/experimentation/tests/fixtures/experiments/page-level-v2.html
new file mode 100644
index 00000000..9ff94a12
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/page-level-v2.html
@@ -0,0 +1,7 @@
+
+
+
+
+ Hello v2!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/page-level.html b/plugins/experimentation/tests/fixtures/experiments/page-level.html
new file mode 100644
index 00000000..03467640
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/page-level.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+ Hello World!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/section-level-v1.html b/plugins/experimentation/tests/fixtures/experiments/section-level-v1.html
new file mode 100644
index 00000000..17dc08dc
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/section-level-v1.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+ Hello v1!
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/section-level-v2.html b/plugins/experimentation/tests/fixtures/experiments/section-level-v2.html
new file mode 100644
index 00000000..d057125e
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/section-level-v2.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+ Hello v2!
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/experiments/section-level.html b/plugins/experimentation/tests/fixtures/experiments/section-level.html
new file mode 100644
index 00000000..bf66e92b
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/experiments/section-level.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/global.html b/plugins/experimentation/tests/fixtures/global.html
new file mode 100644
index 00000000..70f2c9ff
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/global.html
@@ -0,0 +1,8 @@
+
+
+
+
+
+ Hello World!
+
+
\ No newline at end of file
diff --git a/plugins/experimentation/tests/fixtures/scripts.js b/plugins/experimentation/tests/fixtures/scripts.js
new file mode 100644
index 00000000..e763cb30
--- /dev/null
+++ b/plugins/experimentation/tests/fixtures/scripts.js
@@ -0,0 +1,103 @@
+import {
+ buildBlock,
+ decorateButtons,
+ decorateIcons,
+ decorateSections,
+ decorateBlocks,
+ decorateTemplateAndTheme,
+ waitForLCP,
+ loadBlocks,
+} from './aem.js';
+
+const LCP_BLOCKS = []; // add your LCP blocks to the list
+
+/**
+ * Builds hero block and prepends to main in a new section.
+ * @param {Element} main The container element
+ */
+function buildHeroBlock(main) {
+ const h1 = main.querySelector('h1');
+ const picture = main.querySelector('picture');
+ // eslint-disable-next-line no-bitwise
+ if (h1 && picture && (h1.compareDocumentPosition(picture) & Node.DOCUMENT_POSITION_PRECEDING)) {
+ const section = document.createElement('div');
+ section.append(buildBlock('hero', { elems: [picture, h1] }));
+ main.prepend(section);
+ }
+}
+
+/**
+ * Builds all synthetic blocks in a container element.
+ * @param {Element} main The container element
+ */
+function buildAutoBlocks(main) {
+ try {
+ buildHeroBlock(main);
+ } catch (error) {
+ // eslint-disable-next-line no-console
+ console.error('Auto Blocking failed', error);
+ }
+}
+
+/**
+ * Decorates the main element.
+ * @param {Element} main The main element
+ */
+// eslint-disable-next-line import/prefer-default-export
+export function decorateMain(main) {
+ // hopefully forward compatible button decoration
+ decorateButtons(main);
+ decorateIcons(main);
+ buildAutoBlocks(main);
+ decorateSections(main);
+ decorateBlocks(main);
+}
+
+/**
+ * Loads everything needed to get to LCP.
+ * @param {Element} doc The container element
+ */
+async function loadEager(doc) {
+ document.documentElement.lang = 'en';
+ decorateTemplateAndTheme();
+
+ // Add below snippet early in the eager phase
+ if (document.head.querySelector('[name^="experiment"],[name^="campaign-"],[name^="audience-"]')
+ || [...document.querySelectorAll('.section-metadata div')].some((d) => d.textContent.match(/Experiment|Campaign|Audience/i))) {
+ // eslint-disable-next-line import/no-absolute-path, import/no-unresolved
+ const { loadEager: runEager } = await import('/src/index.js');
+ await runEager(document, { audiences: window.AUDIENCES || {} });
+ }
+
+ const main = doc.querySelector('main');
+ if (main) {
+ decorateMain(main);
+ document.body.classList.add('appear');
+ await waitForLCP(LCP_BLOCKS);
+ }
+}
+
+/**
+ * Loads everything that doesn't need to be delayed.
+ * @param {Element} doc The container element
+ */
+async function loadLazy(doc) {
+ const main = doc.querySelector('main');
+ await loadBlocks(main);
+}
+
+/**
+ * Loads everything that happens a lot later,
+ * without impacting the user experience.
+ */
+function loadDelayed() {
+ // load anything that can be postponed to the latest here
+}
+
+async function loadPage() {
+ await loadEager(document);
+ await loadLazy(document);
+ loadDelayed();
+}
+
+loadPage();
diff --git a/plugins/experimentation/tests/global.test.js b/plugins/experimentation/tests/global.test.js
new file mode 100644
index 00000000..5f38d617
--- /dev/null
+++ b/plugins/experimentation/tests/global.test.js
@@ -0,0 +1,20 @@
+/* eslint-disable import/no-extraneous-dependencies */
+import { test, expect } from '@playwright/test';
+import { track } from './coverage.js';
+
+track(test);
+
+test.describe('Plugin config', () => {
+ test('debug statements are shown in dev/stage', async ({ page }) => {
+ await page.goto('/tests/fixtures/global');
+ await page.addScriptTag({ content: 'import { setDebugMode } from "/src/index.js"; window.setDebugMode = setDebugMode;', type: 'module' });
+ expect(await page.evaluate(async () => window.setDebugMode(new URL('http://localhost:3000'), {}))).toEqual(true);
+ expect(await page.evaluate(async () => window.setDebugMode(new URL('https://ref--repo--org.hlx.page/'), {}))).toEqual(true);
+ expect(await page.evaluate(async () => window.setDebugMode(new URL('https://ref--repo--org.hlx.live/'), {}))).toEqual(false);
+ expect(await page.evaluate(async () => window.setDebugMode(new URL('https://ref--repo--org.hlx.live/'), { isProd: () => false }))).toEqual(true);
+ expect(await page.evaluate(async () => window.setDebugMode(new URL('https://stage.foo.com'), { prodHost: 'www.foo.com' }))).toEqual(true);
+ });
+
+ // test.skip('debug statements are not shown on prod');
+ // test.skip('sends event with details when experiment/audience/campaign is run');
+});
diff --git a/plugins/experimentation/tests/setup.js b/plugins/experimentation/tests/setup.js
new file mode 100644
index 00000000..72408938
--- /dev/null
+++ b/plugins/experimentation/tests/setup.js
@@ -0,0 +1,5 @@
+import { start } from './coverage.js';
+
+export default async function setup() {
+ await start();
+}
diff --git a/plugins/experimentation/tests/teardown.js b/plugins/experimentation/tests/teardown.js
new file mode 100644
index 00000000..553211fc
--- /dev/null
+++ b/plugins/experimentation/tests/teardown.js
@@ -0,0 +1,5 @@
+import { end } from './coverage.js';
+
+export default async function teardown() {
+ await end();
+}
diff --git a/plugins/experimentation/tests/utils.js b/plugins/experimentation/tests/utils.js
new file mode 100644
index 00000000..1df0890e
--- /dev/null
+++ b/plugins/experimentation/tests/utils.js
@@ -0,0 +1,34 @@
+import { expect } from '@playwright/test';
+
+async function waitForNamespace(page, namespace) {
+ await expect(async () => {
+ expect(await page.evaluate((ns) => window.hlx[ns], namespace)).toBeDefined();
+ }).toPass();
+ // Wait for the fragments to decorate
+ await new Promise((res) => { setTimeout(res); });
+}
+
+export async function goToAndRunAudience(page, url) {
+ await page.goto(url);
+ await waitForNamespace(page, 'audiences');
+}
+
+export async function goToAndRunCampaign(page, url) {
+ await page.goto(url);
+ await waitForNamespace(page, 'campaigns');
+}
+
+export async function goToAndRunExperiment(page, url) {
+ await page.goto(url);
+ await waitForNamespace(page, 'experiments');
+}
+
+export async function waitForDomEvent(page, eventName) {
+ await page.addInitScript((name) => {
+ // Override the prototype
+ window.eventPromise = new Promise((resolve) => {
+ document.addEventListener(name, (ev) => resolve(ev.detail));
+ });
+ }, eventName);
+ return async () => await window.eventPromise;
+}
diff --git a/scripts/scripts.js b/scripts/scripts.js
index 3ed722bb..d2637df3 100644
--- a/scripts/scripts.js
+++ b/scripts/scripts.js
@@ -1,16 +1,16 @@
import {
sampleRUM,
buildBlock,
- getAllMetadata,
- getMetadata,
loadHeader,
loadFooter,
decorateButtons,
decorateIcons,
decorateSections,
+ decorateBlock,
decorateBlocks,
decorateTemplateAndTheme,
waitForLCP,
+ loadBlock,
loadBlocks,
loadCSS,
} from './lib-franklin.js';
@@ -40,9 +40,10 @@ window.hlx.plugins.add('rum-conversion', {
});
window.hlx.plugins.add('experimentation', {
- condition: () => getMetadata('experiment')
- || Object.keys(getAllMetadata('campaign')).length
- || Object.keys(getAllMetadata('audience')).length,
+ condition: () => document.head.querySelector('[name^="experiment"],[name^="campaign-"],[name^="audience-"]')
+ || document.head.querySelector('[property^="campaign:-"],[property^="audience:-"]')
+ || document.querySelector('.section[class*="experiment-"],.section[class*="audience-"],.section[class*="campaign-"]')
+ || [...document.querySelectorAll('.section-metadata div')].some((d) => d.textContent.match(/Experiment|Campaign|Audience/i)),
options: { audiences: AUDIENCES },
load: 'eager',
url: '/plugins/experimentation/src/index.js',
@@ -182,7 +183,6 @@ export function decorateMain(main) {
async function loadEager(doc) {
document.documentElement.lang = 'en';
decorateTemplateAndTheme();
-
await window.hlx.plugins.run('loadEager');
// load demo config
@@ -275,6 +275,28 @@ async function loadPage() {
await setupAnalytics;
}
+// Properly decorate fragments that were pulled in
+document.addEventListener('aem:experimentation', (ev) => {
+ // Do not redecorate the default content
+ if (ev.detail.variant === 'control' || ev.detail?.campaign === 'default' || ev.detail?.audience === 'default') {
+ return;
+ }
+ // Rebuild the autoblock as needed
+ if (ev.detail.element.classList.contains('hero')) {
+ const parent = ev.detail.element.parentElement.parentElement;
+ [...ev.detail.element.children].reverse().forEach((el) => parent.prepend(el));
+ ev.detail.element.remove();
+ // Rebuild and redecorate the hero block
+ buildHeroBlock(parent);
+ decorateBlocks(parent);
+ loadBlocks(parent);
+ } else if (ev.detail.element.classList.contains('block')) {
+ // Otherwise, just reset the replaced blocks and redecorate them
+ decorateBlock(ev.detail.element);
+ loadBlock(ev.detail.element);
+ }
+});
+
const cwv = {};
// Forward the RUM CWV cached measurements to edge using WebSDK before the page unloads